callback 和 promise 性能差距疑问

2021-07-16 20:27:14 +08:00
 kebyn

callback

import * as fs from 'fs';
import * as path from 'path';
function list_dir(dir: string) {
    fs.readdir(dir, 'utf-8', (err, files) => {
        files.forEach(file => {
            file = path.join(dir, file)
            fs.stat(file, (err, stat) => {
                if (stat.isDirectory()) {
                    list_dir(file)
                }
                if (stat.isFile()) {
                    file
                    // console.log("%O", file);
                }
            })
        });
    })
}

list_dir('.')

promise

import * as util from 'util';
import * as fs from 'fs';
import * as path from 'path';
async function list_dir(dir: string) {
    const readdir = util.promisify(fs.readdir);
    const stat = util.promisify(fs.stat);
    const files = await readdir(dir, 'utf-8')
    files.forEach(async file => {
        file = path.join(dir, file)
        const state = await stat(file)
        if (state.isDirectory()) {
            await list_dir(file)
        }
        if (state.isFile()) {
            file
            // console.log("%O", file);
        }
    })

}

list_dir('.')

性能测试结果

node ➜ /workspaces/typescript $ time node promise.js && time node callback.js

real    0m1.140s
user    0m1.136s
sys     0m1.292s

real    0m0.377s
user    0m0.368s
sys     0m0.534s
node ➜ /workspaces/typescript $ time node promise.js && time node callback.js

real    0m1.062s
user    0m1.132s
sys     0m1.184s

real    0m0.538s
user    0m0.470s
sys     0m0.784s
node ➜ /workspaces/typescript $ time node promise.js && time node callback.js

real    0m1.194s
user    0m1.221s
sys     0m1.308s

real    0m0.436s
user    0m0.393s
sys     0m0.651s
node ➜ /workspaces/typescript $ time node promise.js && time node callback.js

real    0m1.024s
user    0m1.165s
sys     0m1.027s

real    0m0.416s
user    0m0.313s
sys     0m0.653s
node ➜ /workspaces/typescript $ nodejs --version
v16.3.0
node ➜ /workspaces/typescript $ tsc --version
Version 4.3.5

有性能差异可以理解,但是这个性能差异过大,请问各位是我的写法有问题,还是其它原因导致的呢?

5188 次点击
所在节点    Node.js
24 条回复
CokeMine
2021-07-19 17:19:54 +08:00
async 和 forEach 一起写一般 IDE 会有提示吧。
不是很清楚,试试楼上的写法再测一下
libook
2021-07-19 18:54:21 +08:00
我从 ES6 正式发布之后就一直在关注 V8 的 promise 性能情况,V8 官方有个测试用例 https://github.com/v8/promise-performance-tests
你可以 clone 跑一下看看,涵盖了原生 promise 、async/await 和主流的 promise 库的性能测试。我是见证了从一开始被 bluebird 虐逐渐到完爆 bluebird 。不过这个用例里面没有 callback,你可以参考其他的例子自己写一个。

这种测试最好不要引入 fs,因为文件系统是由操作系统管理调度的,有些操作系统比如 Linux 会有一些奇淫技巧的缓存优化,所以要测的话就测语法本身的计算性能,看语法糖是否会带来额外的计算性能损耗,或者是否反而提升了计算效率。
TomVista
2021-07-20 09:28:26 +08:00
@Austaras 这是正确答案
HB9527
2021-08-03 17:57:00 +08:00
重启电脑,先运行 callback.js 再运行 promise.js 试试,vfs cache~~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/789987

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX