Tôi đã lược tả một số mã cũ mà tôi đã kế thừa với cProfile. Có một loạt các thay đổi mà tôi đã thực hiện đã giúp (như sử dụng phần mở rộng C của simplejson!).Tăng tốc độ ghi vào các tệp
Về cơ bản, tập lệnh này đang xuất dữ liệu từ một hệ thống sang tệp chiều rộng cố định ASCII. Mỗi hàng là một bản ghi và nó có nhiều giá trị. Mỗi dòng là 7158 ký tự và chứa một tấn không gian. Tổng số bản ghi là 1,5 triệu bản ghi. Mỗi hàng được tạo ra tại một thời điểm, và mất một thời gian (5-10 hàng một giây).
Khi mỗi hàng được tạo, nó được ghi vào đĩa đơn giản nhất có thể. Hồ sơ chỉ ra rằng khoảng 19-20% tổng thời gian được chi tiêu trong file.write()
. Đối với một trường hợp thử nghiệm 1.500 hàng là 20 giây. Tôi muốn giảm số đó.
Giờ có vẻ như chiến thắng tiếp theo sẽ giảm lượng thời gian dành cho đĩa. Tôi muốn giảm nó, nếu có thể. Tôi có thể giữ một bộ nhớ đệm của các bản ghi trong bộ nhớ, nhưng tôi không thể đợi cho đến khi kết thúc và đổ tất cả cùng một lúc.
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()
Suy nghĩ đầu tiên của tôi là lưu một bộ nhớ cache vào danh sách và ghi chúng theo lô. Điều đó có nhanh hơn không? Một cái gì đó như:
rows = []
for c, (recordid, values) in enumerate(generatevalues()):
rows.append(prep_row(recordid, values))
if c % 117 == 0:
fd.write('\n'.join(rows))
rows = []
Suy nghĩ thứ hai của tôi là sử dụng một sợi khác, nhưng điều đó khiến tôi muốn chết bên trong.
Nút cổ chai của ứng dụng là gì? –
Tôi nghĩ tôi đã rõ ràng. Đó là chi tiêu 20% thời gian của nó ghi vào đĩa một hàng tại một thời điểm. – chmullig
Vâng, thực hiện thay đổi và cấu hình nó? Nó hy vọng nó sẽ có ít ảnh hưởng, vì tập tin I/O thường là dòng đệm ... hoặc vì vậy tôi giả định. – delnan