我有4GB big_file.txt
,所以如果我尝试:
cat big_file.txt |
python3 -c "print( open('/dev/stdin').read() )" |
less
我的RAM爆炸了,我死了。但如果我:
cat big_file.txt |
python3 -c "
for line in open('/dev/stdin'):
print(line)
" |
less
RAM静止不动,我可以向下滚动,通过less
按需读取文件,甚至通过python。我甚至可以在打印前处理这条线,一切正常。
所以我想我可以:
seq 1 100 |
python3 -c "
fib = lambda n: n if n < 2 else fib(n - 1) + fib(n - 2)
for line in open('/dev/stdin'):
print( fib( int(line) ) )
" |
less
但这会打击CPU,我又死了。
更改print
和sys.stdout.write
的{{1}}可以至少在sys.stdout.flush
中查看结果,但即使我不向下滚动,CPU也会保持100% ,显然执行我没有要求的线。
起初我认为这是一个“阅读块”的事情,好像有最少量的数据需要通过管道输送,所以我试过了:
less
(请注意,此seq -10000 100 |
python3 -c "
import sys
fib = lambda n: n if n < 2 else fib(n - 1) + fib(n - 2)
for line in open('/dev/stdin', 'r'):
sys.stdout.write( str( fib( int(line) ) ) + '\n' )
sys.stdout.flush()
" |
less
只是回应任何fib
)
但仍然没有运气。
我也试过了
n < 2
发生了什么事?为什么在seq -10000 100 > numbers.txt && cat numbers.txt | python3 -c blablabla
示例中我可以根据需要进行管道,而big_file.txt
我不能管道?
答案 0 :(得分:1)
less
执行的预读量远大于CPU优化的测试。尝试:
seq 1000000 | tee test.out | less
并查看test.out
的大小。在我的系统上,它是80KB。
fib
结果的80KB预读将确实会耗尽你的CPU。
如果你想了解没有 less
的管道缓冲,你可以做类似的事情:
seq 1000000 | tee test.out | { while read; do read </dev/tty; done; }
...它往往会有点小(在我的系统上,72KB),但仍然在大多数现代的unixlikes非常重要。