节点.js动态 JavaScript 执行性能

node.js dynamic javascript execution performance

本文关键字:执行 性能 JavaScript 动态 js 节点      更新时间:2023-09-26

我想在文件的每一行上执行一段任意的 - 用户提供的 - javascript 代码。我创建了一个简单的节点命令行应用程序,例如,它只需获取每一行并输出其长度:

#!/usr/bin/env node
// eachline.js - execute some js per line in a file
var fs = require('fs'),
    readline = require('readline');
    vm = require('vm');
var args = process.argv.slice(2);
if (args.length < 1) {
    console.log("Usage: eachline.js FILENAME")
    process.exit(code=1)
}
var rd = readline.createInterface({
    input: fs.createReadStream(args[0]),
    output: process.stdout,
    terminal: false
});
var context = vm.createContext({});
// this snippet should be user supplied, arbitrary javascript
var script = vm.createScript('output = input.length');
rd.on('line', function(line) {
    context.input = line;
    script.runInContext(context);
    console.log(context.output);
});

性能不是最佳的。对于包含 100 万行的文件,需要几分钟时间:

$ time ./eachline.js 1M.txt > /dev/null
real    4m14.366s
user    4m12.200s
sys     0m4.545s

使用awk这个简单的操作大约需要五秒钟。使用类似的程序,执行任意javascript的时间略多于十秒。

我以前没有使用过node,所以上面的程序是我对解决方案的第一个没有根据的猜测。如何提高性能?

编辑:上面的源代码要点:https://gist.github.com/miku/31864156938fcd0c8430


目标是拥有一个可以在文件的每一行上快速运行任意javascript的程序。

试试这个:

var context = vm.createContext({});
// this snippet should be user supplied, arbitrary javascript
var script = vm.createScript('(function (input) { return input.length; })');
var fn = script.runInContext(context);
rd.on('line', function(line) {
    console.log(fn(line));
});

这个想法是将提供的表达式包装在一个函数中,计算脚本,然后使用该函数。我认为 v8 不会优化 script 内部的代码,因为它不应该运行多次。