2017-11-06 8 views
-2

파이썬에서는 거대한 부동 소수점 값 목록 (약 3 천만 개 값)이 있습니다. 나는 각각을 리틀 엔디 언 형식의 4 바이트 값으로 변환하고 모든 것을 이진 파일에 순서대로 작성해야한다.거대한 바이트 목록을 파일에 기록 할 때 성능을 향상시키는 방법은 무엇입니까?

데이터가 수천 개 또는 100,000 개가 넘는 목록의 경우 코드가 올바르게 작동합니다. 그러나 데이터가 증가하면 파일을 처리하고 쓰는 데 시간이 걸립니다. 파일을보다 효율적으로 작성하는 데 사용할 수있는 최적화 기술은 무엇입니까?

this 블로그에 제안 된대로 bytearray를 사용하여 파일에 대한 모든 작은 글을 대체하려고합니다. 그러나 여전히 성능은 만족스럽지 않습니다.

또한 다중 CPU (concurrent.futures.ProcessPoolExecutor())를 사용하여 단일 CPU 코어 대신 시스템의 모든 코어를 활용하려고했습니다. 그러나 여전히 실행을 완료하는 데 더 많은 시간이 걸립니다.

누구든지 나에게이 문제에 대한 성능 향상 방법 (시간 및 메모리 측면에서)을 제안 할 수 있습니까? 여기

내 코드입니다 :

def process_value (value): 
    hex_value = hex(struct.unpack('<I', struct.pack('<f', value))[0]) 
    if len(hex_value.split('x')[1]) < 8: 
     hex_value = hex_value[:2] + ('0' * (8 - len(hex_value.split('x')[1]))) + hex_value[2:] 

    dec1 = int(hex_value.split('x')[1][0] + hex_value.split('x')[1][1], 16) 
    dec2 = int(hex_value.split('x')[1][2]+hex_value.split('x')[1][3],16) 
    dec3 = int(hex_valur.split('x')[1][4]+hex_value.split('x')[1][5],16) 
    dec4 = int(hex_value.split('x')[1][6]+hex_value.split('x')[1][7],16) 
    msg = bytearray([dec4,dec3,dec2,dec1]) 
    return msg 

def main_function(fp, values): 
    msg = bytearray() 
    for val in values: 
     msg.extend (process_value(val)) 
    fp.write(msg) 
+3

부동 소수점 값이 3 천만 개가 넘는 코드를 작성하는 경우 [NumPy] (http://www.numpy.org/)를 살펴볼 수 있습니다. – user2357112

+2

NumPy와 mmap가 가장 빠른 것 같습니다. –

+0

'values ​​'에 대한 작은 예제를 줄 수 있습니까? –

답변

2

당신이 그들을 쓰기 전에 모든 수레를 변환하려고 한 다음 한 번에 결과 데이터를 쓸 수있다 : 값의 양

import struct  

my_floats = [1.111, 1.222, 1.333, 1.444]  

with open('floats.bin', 'wb') as f_output: 
    f_output.write(struct.pack('<{}f'.format(len(my_floats)), *my_floats)) 

당신 있습니다. 큰 블록에서이 작업을 수행해야 할 수도 있습니다.

import struct  

def blocks(data, n): 
    for i in xrange(0, len(data), n): 
     yield data[i:i+n] 

my_floats = [1.111, 1.222, 1.333, 1.444]  

with open('floats.bin', 'wb') as f_output: 
    for block in blocks(my_floats, 10000): 
     f_output.write(struct.pack('<{}f'.format(len(block)), *block)) 

출력은 struct.pack()은 파일에 직접 쓰기 위해 올바른 2 진 형식이어야합니다. 파일은 바이너리 모드로 열어야합니다. wb이 사용됩니다.

+0

답변 해 주셔서 감사합니다. 블럭 단위로 쓰는 것은 실제로 시간과 메모리를 절약합니다. – Lakshmi

+0

도움이 되니 기쁩니다. 작업이 끝나면 위/아래 버튼 아래의 회색 눈금을 클릭하여 승인 된 해결책으로 답변을 선택하는 것을 잊지 마십시오. –