2013-03-12 6 views
4

파이썬 함수를 cython으로 컴파일하고 싶습니다. 일부 파일을 건너 뛰고 전체 파일을 읽지 않고 슬라이싱하여 메모리가 부족해지기 때문입니다. 나는 이런 식으로 뭔가 가지고 올 수 :파일 핸들을 cython 함수에 전달하십시오.

def FromFileSkip(fid, count=1, skip=0):    
     if skip>=0: 
      data = numpy.zeros(count) 
      k = 0 
      while k<count: 
       try: 
        data[k] = numpy.fromfile(fid, count=1, dtype=dtype) 
        fid.seek(skip, 1) 
        k +=1 
       except ValueError: 
        data = data[:k] 
        break 
      return data 

을 한 후 나는이 같은 기능을 사용할 수 있습니다 사이 썬과 기능 "FromFileSkip을"컴파일, 그러나

f = open(filename) 
data = FromFileSkip(f,... 

을, 나는 정의하고 싶습니다 함수에 관련된 모든 유형, 그래서 "fid"뿐만 아니라 파일 핸들러. 그것은 "표준"타입이 아니기 때문에 어떻게 cython에서 타입을 정의 할 수 있습니까? 정수. 감사합니다. .

+3

왜 변수를 입력해야합니까? 이후 파이썬 개체가 당신이 어떤 속도를 얻을 실 거예요. – Bakuriu

+0

클래스 변수에 할당하려면'object' 유형을 사용하십시오. –

+1

그래서 파일 핸들을 입력하면별로 바뀌지 않을까요? 예외없이 모든 변수를 입력하면 일부 변수를 입력하는 것보다 성능이 향상된다고 생각했습니다. – user2061949

답변

5

fid 유형을 정의하는 것은 도움이되지 않습니다. 왜냐하면 파이썬 기능을 호출하는 데 여전히 많은 비용이 들기 때문입니다. "-a"플래그로 예제를 컴파일 해보고 무슨 뜻인지 알아보십시오. 그러나 파일 처리에 하위 수준의 C 함수를 사용하여 루프에서 파이썬 오버 헤드를 피할 수 있습니다. 예를 위해, I 데이터 바로 파일의 시작 부분에서 시작한다고 가정 및 유형 cython -a example.pyx의 출력은 루프 내부에 파이썬 오버 헤드를 나타낸다 없다고 double

from libc.stdio cimport *                 

cdef extern from "stdio.h": 
    FILE *fdopen(int, const char *) 

import numpy as np 
cimport numpy as np 

DTYPE = np.double # or whatever your type is 
ctypedef np.double_t DTYPE_t # or whatever your type is 

def FromFileSkip(fid, int count=1, int skip=0): 
    cdef int k 
    cdef FILE* cfile 
    cdef np.ndarray[DTYPE_t, ndim=1] data 
    cdef DTYPE_t* data_ptr 

    cfile = fdopen(fid.fileno(), 'rb') # attach the stream 
    data = np.zeros(count).astype(DTYPE) 
    data_ptr = <DTYPE_t*>data.data 

    # maybe skip some header bytes here 
    # ... 

    for k in range(count): 
     if fread(<void*>(data_ptr + k), sizeof(DTYPE_t), 1, cfile) < 0: 
      break 
     if fseek(cfile, skip, SEEK_CUR): 
      break 

    return data 

참고된다.