Khi làm việc trên một tập lệnh hoàn toàn khác, tôi đã học được rằng với 29 triệu dòng văn bản, việc sử dụng seek()
và vận hành trên dữ liệu tạm thời thường nhanh hơn trên cơ sở từng dòng. Ý tưởng tương tự được áp dụng trong kịch bản dưới đây: chúng tôi mở tệp và thay vì lặp qua mở và đóng tệp (có thể thêm chi phí, ngay cả khi không đáng kể), chúng tôi giữ tệp mở và tìm lại từ đầu.
#!/usr/bin/env python3
from __future__ import print_function
import sys,os
def error_out(string):
sys.stderr.write(string+"\n")
sys.exit(1)
def read_bytewise(fp):
data = fp.read(1024)
print(data.decode(),end="",flush=True)
while data:
data = fp.read(1024)
print(data.decode(),end="",flush=True)
#fp.seek(0,1)
def main():
howmany = int(sys.argv[1]) + 1
if not os.path.isfile(sys.argv[2]):
error_out("Needs a valid file")
fp = open(sys.argv[2],'rb')
for i in range(1,howmany):
#print(i)
fp.seek(0)
read_bytewise(fp)
fp.close()
if __name__ == '__main__': main()
Bản thân kịch bản sử dụng khá đơn giản:
./repeat_text.py <INT> <TEXT.txt>
Đối với tệp văn bản 3 dòng và 1000 lần lặp, nó khá ổn, khoảng 0,1 giây:
$ /usr/bin/time ./repeat_text.py 1000 input.txt > /dev/null
0.10user 0.00system 0:00.23elapsed 45%CPU (0avgtext+0avgdata 9172maxresident)k
0inputs+0outputs (0major+1033minor)pagefaults 0swaps
Bản thân kịch bản không thanh lịch nhất, có thể rút ngắn, nhưng thực hiện công việc. Tất nhiên, tôi đã thêm một vài bit bổ sung ở đây và ở đó, như error_out()
chức năng, không cần thiết - đó chỉ là một liên lạc nhỏ thân thiện với người dùng.