cProfile으로 상속 한 레거시 코드를 프로파일했습니다. simplejson의 C 확장을 사용하는 것과 같이 도움이 된 많은 변화가있었습니다.파일 쓰기 속도 향상
기본적으로이 스크립트는 한 시스템에서 ASCII 고정 폭 파일로 데이터를 내보내고 있습니다. 각 행은 레코드이고 많은 값을가집니다. 각 줄은 7158 자이며 1 톤의 공백이 있습니다. 총 레코드 수는 150 만 레코드입니다. 각 행은 한 번에 하나씩 생성되며 잠시 (5-10 행을 초 단위로) 소요됩니다.
각 행이 생성되면 가능한 한 간단하게 디스크에 기록됩니다. 프로파일 링은 전체 시간의 19-20 %가 file.write()
에 소비되었음을 나타냅니다. 1,500 행의 테스트 케이스의 경우 20 초입니다. 그 숫자를 줄이고 싶습니다.
이제는 디스크에 쓰는 데 드는 시간이 줄어들 것입니다. 가능하다면 그것을 줄이고 싶습니다. 메모리 캐시를 보관할 수는 있지만 끝날 때까지 기다릴 수는 없으며 한번에 모두 덤프 할 수 있습니다.
fd = open(data_file, 'w')
for c, (recordid, values) in enumerate(generatevalues()):
row = prep_row(recordid, values)
fd.write(row)
if c % 117 == 0:
if limit > 0 and c >= limit:
break
sys.stdout.write('\r%s @ %s' % (str(c + 1).rjust(7), datetime.now()))
sys.stdout.flush()
내 첫 번째 생각은 목록의 레코드 캐시를 유지하고 일괄 적으로 작성하는 것입니다. 그게 더 빠를까요? 뭔가 같은 :
rows = []
for c, (recordid, values) in enumerate(generatevalues()):
rows.append(prep_row(recordid, values))
if c % 117 == 0:
fd.write('\n'.join(rows))
rows = []
내 생각은 또 다른 스레드를 사용하는 것입니다,하지만 그 안에 죽고 싶어.
응용 프로그램의 병목 현상은 무엇입니까? –
나는 내가 분명하다고 생각했다. 한 번에 한 행씩 디스크에 쓰는 시간의 20 %를 소비합니다. – chmullig
글쎄, 변경하고 프로필? 파일 I/O가 일반적으로 버퍼에 저장되어 있기 때문에 거의 효과가 없을 것으로 예상됩니다. – delnan