为什么node.js在文件读取时比python更快?

时间:2016-12-17 19:12:50

标签: python node.js python-3.x

我在同步读取文件(48KB)中的node.js与python的分析。

Node.js代码

var fs = require('fs');
var stime = new Date().getTime() / 1000;

for (var i=0; i<1000; i++){
  var content = fs.readFileSync('npm-debug.log');
}

console.log("Total time took is: " + ((new Date().getTime() / 1000) - stime));

Python代码

import time
stime = time.time()
for i in range(1000):
    with open('npm-debug.log', mode='r') as infile:
        ax = infile.read();

print("Total time is: " + str(time.time() - stime));

时间如下:

$ python test.py
Total time is: 0.5195660591125488

$ node test.js
Total time took is: 0.25799989700317383

区别在哪里?

  1. 在文件IO或
  2. Python list ds allocation
  3. 或者我不是在比较苹果和苹果吗?

    修改

    1. 将python的readlines()更新为read()以进行良好的比较
    2. 将迭代次数更改为1000
    3. 目的:

      要理解node.js中的真实性比python慢​​于C类的东西,如果在这个上下文中的哪个位置那么慢。

1 个答案:

答案 0 :(得分:4)

readlines在文件中返回一行,因此它必须通过char读取数据char,不断地将当前字符与任何换行符进行比较,并保持编写一系列行。

这比简单的file.read()更复杂,它与Node.js的功能相同。

此外,Python脚本计算的长度是行数,而Node.js得到的字符数。

如果您想要更快的速度,请使用os.open代替open

import os, time


def Test_os(n):
    for x in range(n):
        f = os.open('Speed test.py', os.O_RDONLY)
        data = ""
        t = os.read(f, 1048576).decode('utf8')
        while t:
            data += t
            t = os.read(f, 1048576).decode('utf8')
        os.close(f)

def Test_open(n):
    for x in range(n):
        with open('Speed test.py') as f:
            data = f.read()

s = time.monotonic()
Test_os(500000)
print(time.monotonic() - s)

s = time.monotonic()
Test_open(500000)
print(time.monotonic() - s)

在我的计算机os.open上比open快几秒。输出如下:

53.68909174999999
58.12600833400029

正如您所看到的,open4.4os.open秒,尽管随着运行次数减少,这种差异也会减少。

此外,您应该尝试调整os.read函数的缓冲区大小,因为不同的值可能会给出非常不同的时间:

timings

此处'operation'表示Test_os 的单次调用。

如果你摆脱字节'解码并使用io.BytesIO而不仅仅是bytes个对象,你将获得相当大的加速:

def Test_os(n, buf):
    for x in range(n):
        f = os.open('test.txt', os.O_RDONLY)
        data = io.BytesIO()
        while data.write(os.read(f, buf)):
            ...
        os.close(f)

speedup

因此,现在最好的结果是每次调用0.038秒,而不是0.052(加速率约为37%)。