2013-05-30 3 views
13

현재 저는 파이썬으로 이미지를 검색하고 있습니다. 이 예제에서 이미지에서 추출 된 키포인트와 디스크립터는 numpy.array으로 표시됩니다. 모양 (2000, 5)과 모양의 후자 (2000, 128) 중 첫 번째 것. 둘 다 dtype=numpy.float32의 값만 포함합니다.숫자 데이터로 cickle보다 pickle이 빠릅니까?

그래서 추출 된 키포인트와 설명자를 저장하기 위해 어떤 형식을 사용해야하는지 궁금합니다. 나는. 저는 항상 2 개의 파일을 저장합니다 : 하나는 키포인트 용이고 하나는 설명자 용입니다. 이것은 측정에서 하나의 단계로 간주됩니다. 내가 pickle, cPickle 비교 (모두 프로토콜 0, 2)와 NumPy와의 바이너리 형식 .pny 결과 정말 나를 혼동 :

enter image description here

나는 항상 cPicklepickle 모듈보다 더 빨리 있어야한다 생각했다. 하지만 특히 프로토콜 0을 사용하는로드 시간은 실제로 결과에 크게 영향을 미칩니다. 누구든지 이에 대한 설명이 있습니까? 내가 숫자 데이터 만 사용하고 있기 때문입니까? 이상한 ...

PS를 보인다 : 내 코드에서 나는 기본적으로 각 기술을 통해 1000 배 (number=1000)을 반복하고있어 결국 측정 시간을 평균 :

timer = time.time 

    print 'npy save...' 
    t0 = timer() 
    for i in range(number): 
     numpy.save(npy_kp_path, kp) 
     numpy.save(npy_descr_path, descr) 
    t1 = timer() 
    results['npy']['save'] = t1 - t0 

    print 'npy load...' 
    t0 = timer() 
    for i in range(number): 
     kp = numpy.load(npy_kp_path) 
     descr = numpy.load(npy_descr_path) 
    t1 = timer() 
    results['npy']['load'] = t1 - t0 


    print 'pickle protocol 0 save...' 
    t0 = timer() 
    for i in range(number): 
     with open(pkl0_descr_path, 'wb') as f: 
      pickle.dump(descr, f, protocol=0) 
     with open(pkl0_kp_path, 'wb') as f: 
      pickle.dump(kp, f, protocol=0) 
    t1 = timer() 
    results['pkl0']['save'] = t1 - t0 

    print 'pickle protocol 0 load...' 
    t0 = timer() 
    for i in range(number): 
     with open(pkl0_descr_path, 'rb') as f: 
      descr = pickle.load(f) 
     with open(pkl0_kp_path, 'rb') as f: 
      kp = pickle.load(f) 
    t1 = timer() 
    results['pkl0']['load'] = t1 - t0 


    print 'cPickle protocol 0 save...' 
    t0 = timer() 
    for i in range(number): 
     with open(cpkl0_descr_path, 'wb') as f: 
      cPickle.dump(descr, f, protocol=0) 
     with open(cpkl0_kp_path, 'wb') as f: 
      cPickle.dump(kp, f, protocol=0) 
    t1 = timer() 
    results['cpkl0']['save'] = t1 - t0 

    print 'cPickle protocol 0 load...' 
    t0 = timer() 
    for i in range(number): 
     with open(cpkl0_descr_path, 'rb') as f: 
      descr = cPickle.load(f) 
     with open(cpkl0_kp_path, 'rb') as f: 
      kp = cPickle.load(f) 
    t1 = timer() 
    results['cpkl0']['load'] = t1 - t0 


    print 'pickle highest protocol (2) save...' 
    t0 = timer() 
    for i in range(number): 
     with open(pkl2_descr_path, 'wb') as f: 
      pickle.dump(descr, f, protocol=pickle.HIGHEST_PROTOCOL) 
     with open(pkl2_kp_path, 'wb') as f: 
      pickle.dump(kp, f, protocol=pickle.HIGHEST_PROTOCOL) 
    t1 = timer() 
    results['pkl2']['save'] = t1 - t0 

    print 'pickle highest protocol (2) load...' 
    t0 = timer() 
    for i in range(number): 
     with open(pkl2_descr_path, 'rb') as f: 
      descr = pickle.load(f) 
     with open(pkl2_kp_path, 'rb') as f: 
      kp = pickle.load(f) 
    t1 = timer() 
    results['pkl2']['load'] = t1 - t0 


    print 'cPickle highest protocol (2) save...' 
    t0 = timer() 
    for i in range(number): 
     with open(cpkl2_descr_path, 'wb') as f: 
      cPickle.dump(descr, f, protocol=cPickle.HIGHEST_PROTOCOL) 
     with open(cpkl2_kp_path, 'wb') as f: 
      cPickle.dump(kp, f, protocol=cPickle.HIGHEST_PROTOCOL) 
    t1 = timer() 
    results['cpkl2']['save'] = t1 - t0 

    print 'cPickle highest protocol (2) load...' 
    t0 = timer() 
    for i in range(number): 
     with open(cpkl2_descr_path, 'rb') as f: 
      descr = cPickle.load(f) 
     with open(cpkl2_kp_path, 'rb') as f: 
      kp = cPickle.load(f) 
    t1 = timer() 
    results['cpkl2']['load'] = t1 - t0 
+0

나는 오늘이 사실을 알게되었고, 당신의 질문을 찾았습니다. 적어도 최소한의 차이는 있습니다. pickle은 cpickle보다 확실히 빠릅니다. –

답변

6

(의 이진 표현)을 ndarray의 숫자 데이터는 하나의 긴 문자열로 pickle됩니다. 프로토콜 0 파일의 큰 문자열을 unpickling하는 경우 cPickle은 실제로 pickle보다 훨씬 느린 것으로 보입니다. 왜? 내 생각에 pickle은 표준 라이브러리의 잘 튜닝 된 문자열 알고리즘을 사용하고 cPickle은 뒤쳐졌습니다.

위의 관찰은 Python 2.7로 플레이 한 것입니다. 자동으로 C 확장자를 사용하는 Python 3.3은 Python 2.7의 어느 모듈보다 빠르기 때문에이 문제가 수정되었습니다.

+0

파이썬 3.3에서 해결책을 지적 해 주셔서 감사합니다. 내 예제에서는 ideed 2.7을 사용합니다. 체크 아웃 할 것입니다. 3.3 – pklip

+0

@pklip하지만 프로토콜 0 사용을 고집하는 이유는 무엇입니까? 프로토콜 2는 귀하의 타이밍에 따라 빠릅니다. –

+0

"텍스트로 읽을 수있는"파일이 필요하지 않으므로 프로토콜 2를 사용합니다. 나는 일반적으로 3.3을 시험해보고 싶어한다. :) – pklip

관련 문제