Basic Unix paste可以用类似于Python的语言实现(该示例仅适用于两个文件;Unix Paste适用于多个文件):
def paste(fn1, fn2):
with open(fn1) as f1:
with open(fn2) as f2:
for l1 in f1:
l2 = f2.readline()
if l2 != None:
print(l1[:-1] + "\t" + l2[:-1])
else:
print(l1[:-1])
for l2 in f2:
print("\t" + l2[:-1])
import sys
if __name__ == "__main__":
if len(sys.argv) >= 3:
paste(sys.argv[1], sys.argv[2])
任务是在Node.js中实现相同的功能.Importantly,因为输入文件可能很大,所以实现应该逐行读取输入文件,而不是将整个文件读入内存.我想看看如何在没有外部包的情况下使用内置的Node功能来实现这一点.
请注意,使用同步I/O实现Unix Paste很容易,如Python示例所示,但Node不为行读取提供同步I/O.同时,有ways个异步I/O逐行读取一个文件,但联合读取两个文件比较困难,因为两个流不同步.
到目前为止,我能想到的唯一解决方案是使用基本的readAPI实现同步行读取.戴夫·牛顿在 comments 中指出,NPM n-readlines package在read多行代码中实现了这种方法.因为n-READLINS判断每个字节以查找行结束,我怀疑它效率不高,因此执行了microbenchmark,结果如下表所示.对于行读取(不适用于此任务),n读取行的速度是Node Readline实现的3倍,并且比在Python、Perl或Mawk中内置的行读取慢一个数量级.
如何正确实现Unix粘贴?N-readlines使用同步API.一个好的解决方案会更干净、更快吗?
Language | Runtime | Version | Elapsed (s) | User (s) | Sys (s) | Code |
---|---|---|---|---|---|---|
JavaScript | node | 21.5.0 | 6.30 | 5.33 | 0.90 | lc-node.js |
node | 21.5.0 | 22.34 | 20.41 | 2.24 | lc-n-readlines.js | |
bun | 1.0.20 | 4.91 | 5.30 | 1.47 | lc-node.js | |
bun | 1.0.20 | 21.16 | 19.22 | 3.37 | lc-n-readlines.js | |
k8 | 1.0 | 1.49 | 1.06 | 0.37 | lc-k8.js | |
C | clang | 15.0.0 | 0.71 | 0.35 | 0.35 | lc-c.c |
python | python | 3.11.17 | 3.48 | 2.85 | 0.62 | lc-python.py |
perl | perl | 5.34.3 | 1.70 | 1.13 | 0.57 | lc-perl.pl |
awk | mawk | 1.3.4 | 2.08 | 1.27 | 0.80 | lc-awk.awk |
apple awk | ? | 90.06 | 87.90 | 1.12 | lc-awk.awk |