2016-09-09 4 views
3

내가 파일에 두 개의 배열에서 인쇄 번호를 해요 말 :파이썬에서 한 줄씩 파일에 인쇄하는 속도를 올리는 방법은 무엇입니까?

from numpy import random 
number_of_points = 10000 
a = random.rand(number_of_points) 
b = random.rand(number_of_points) 
fh = open('file.txt', 'w') 
for i in range(number_of_points): 
    for j in range(number_of_points): 
     print('%f %f' % (a[i], b[j]), file=fh) 

나는이 빠른 것이 정보를 포함하는 하나의 호출을 보내는 반면, 인쇄 할 수있는 시스템 호출을 많이하고있다 생각합니다. 이 올바른지? 그렇다면 어떻게해야합니까? 이것을 구현하는 더 빠른 방법이 있습니까?

+1

얼마나 느린가요? 테스트를 마친 후에는 너무 느리다는 결론을 얻었습니까? 그렇다면, 그 주범이 반복되는'print' 호출이라고 확신합니까? 범위 (number_of_points)에서)'print ('\ n'. 조인 ([ '% f % f'% (a [i], b [i]))') – TigerhawkT3

+0

내 응용 프로그램에서는이 세그먼트의 속도 향상이 바람직합니다. 핀을 프로파일 링하여 '인쇄'를 범합니다. 중첩 된 for 루프에 대해 위의 작업을 어떻게 수행합니까? 위에서 편집하여 중첩 된 'for' 루프를 포함합니다. – bfletch

+0

@ TigerhawkT3 : 그 제안은 메모리에'str'의 100M 항목'list '를 만들 것입니다. 그리고 모두를 합친 길이가'str'을 필요로하는 피크 RAM으로 생성합니다. 이는 여러 GB 이상의 메모리를 필요로합니다. 단편적인 글을 쓰지 않는 해결책으로 이것을 해결하고 싶지는 않습니다. – ShadowRanger

답변

2

print에는 사용하지 않는 벨소리가 많이 있습니다. 직접 반복 대신 색인을 생성하는 C 스타일 루핑을 사용하고 있습니다. 둘 다 불필요한 오버 헤드가 발생합니다. 파이썬 레벨 작업을 제한하여 C 레이어로 밀어 넣으면 속도를 조금 높일 수 있습니다.

예를 들어,이 경우에, 당신이 가지고있는 전체의 이중 중첩 루프 구조를 대체 할 수 있습니다 : 만들 직접 당신의 중첩 된 루프의 결과와 색인을 생성 product를 사용

import itertools 

# You could use '%f %f\n'.__mod__ as the map function if you like, I just 
# find the modern format strings a little nicer 
fh.writelines(itertools.starmap('{} {}\n'.format, itertools.product(a, b))) 

, starmap + str.format을 회선 및 fh.writelinesstarmap으로 생성 된 생성기를 소모하고 print에 대한 100,000,000 회 호출 대신 모든 출력을 단일 함수 호출로 파일에 직접 작성합니다.

발전기를 생성하고 최종 생성기를 fh.writelines으로 전달하는 고정 비용 (반복 항목 수와는 무관 함) 이외에도 실제 반복, 형식 지정 및 I/O 작업은 전체 C 계층에서 수행됩니다. CPython 참조 인터프리터이므로 매우 빠르게 실행해야합니다.

+0

itertools가 없어도 (OP의 실제 코드뿐만 아니라 그의 예에도 맞지 않을 수도 있음). 'file.write'를 사용하는 것이 좋은 팁입니다. 아마도 인쇄 속도가 두 배 빨라질 것입니다. – tdelaney

+0

@tdelaney'io.TextIOBase.write (s)'와'io.IOBase.writelines (lines)'는'print()'와 비교하여 어떤 성능상의 이점이 있습니까? 'print()'와'io.TextIOBase.write (s)'는 둘 다 라인 단위로 버퍼링하는 반면,'io.IOBase.writelines (lines)'는 모든 라인을 설명하기 위해 버퍼링하는 것 같습니다. 이 올바른지? – bfletch

+1

@bfletch 왜'print'가 느리지 만 줄 버퍼링 문제가 아닌지 나는 모른다. 버퍼링은 파일을 열 때 결정됩니다. 기본적으로 파일 및 파이프는 버퍼링되지 않으므로 터미널은 기본적으로 줄이 버퍼 됨 - 인쇄물은 줄 버퍼가 없습니다. 필자는 테스트에서 파일 버퍼 크기를 16 메가로 늘렸고 시스템 쓰기 횟수가 2000 배로 줄었지만 전반적인 실행 시간은 거의 같았습니다. 쓰기로 변경하면 실행 시간이 40 % . 그래서 '인쇄'의 문제는 시스템 버퍼링이 아니라 느리다는 것입니다. 귀하의 마일리지가 다를 수 있습니다! – tdelaney

관련 문제