为什么V8在Node.JS比我的本地C + +插件更快? [英] Why V8 in Node.JS is faster than in my native C++ addon?
问题描述
为什么我的C ++插件中的Google V8 JavaScript引擎的工作速度明显低于Node.JS?
Why Google's V8 JavaScript engine in my C++ addon works significantly slower than in Node.JS?
我试图编写一些愚蠢的简单代码来生成素数在JavaScript中,通过我的C ++插件和直接在Node.JS中运行它在V8。
I've tried to write some stupidly simple code for generating prime numbers in the JavaScript and ran it in V8 via my C++ addon and directly in Node.JS.
我很震惊,因为两个应该使用相同的JavaScript引擎,已执行相同的代码(以毫秒为单位的时间,越少越好):
I was quite shocked, because both should be using the same JavaScript engine and both have executed the same code (time in milliseconds, less is better):
V8 in Node.JS: 495517
V8 in Node.JS C++ Addon: 623598
这里是JavaScript模块的源代码和C ++ addon运行相同的JavaScript代码(我认为问题不在interop,因为测量的时间直接在JS中工作):
Here is the source of JavaScript module and source of C++ addon that runs same JavaScript code (and I think problem not in the interop, because measuring of time works directly in JS):
index.js :
var jsInNodeJsPrimeGeneratorBenchmark = require("./javascript.js");
var jsInNativePrimeGeneratorBenchmark = require("./native");
console.log("V8 in Node.JS: ", jsInNodeJsPrimeGeneratorBenchmark.primeGeneratorBenchmark());
console.log("V8 in Node.JS C++ Addon: ", jsInNativePrimeGeneratorBenchmark.primeGeneratorBenchmark());
javascript.js :
function primeGeneratorBenchmark() {
var result, primeNumberCounter, i, j, isPrime, start, end;
i = 3;
primeNumberCounter = 1;
start = Date.now();
while (primeNumberCounter < 100000) {
isPrime = true;
for (j = 2; j < i; j++) {
if (i % j === 0) {
isPrime = false;
break;
}
}
if (isPrime) {
result = i;
primeNumberCounter++;
}
i++;
}
end = Date.now();
return end - start;
}
exports.primeGeneratorBenchmark = primeGeneratorBenchmark;
native.cpp :
#include <node.h>
v8::Handle<v8::Value> primeGeneratorBenchmark(const v8::Arguments &arguments);
void registerModule(v8::Handle<v8::Object> target);
v8::Handle<v8::Value> primeGeneratorBenchmark(const v8::Arguments &arguments) {
v8::HandleScope handleScope;
v8::Local<v8::Context> context = arguments.Holder()->CreationContext();
v8::Context::Scope scope(context);
const char *sourceStringC =
"var result, primeNumberCounter, i, j, isPrime, start, end, time;\n"
"i = 3;\n"
"primeNumberCounter = 1;\n"
"start = Date.now();\n"
"while (primeNumberCounter < 100000) {\n"
" isPrime = true;\n"
" for (j = 2; j < i; j++) {\n"
" if (i % j === 0) {\n"
" isPrime = false;\n"
" break;\n"
" }\n"
" }\n"
" if (isPrime) {\n"
" result = i;\n"
" primeNumberCounter++;\n"
" }\n"
" i++;\n"
"}\n"
"end = Date.now();\n"
"time = end - start;\n";
v8::Local<v8::String> sourceStringV8 = v8::String::New(sourceStringC);
v8::Local<v8::Script> script = v8::Script::Compile(sourceStringV8);
script->Run();
v8::Local<v8::Value> timeResult = v8::Context::GetCurrent()->Global()->Get(v8::String::New("time"));
return handleScope.Close(timeResult);
}
void registerModule(v8::Handle<v8::Object> target) {
target->Set(v8::String::NewSymbol("primeGeneratorBenchmark"), v8::FunctionTemplate::New(primeGeneratorBenchmark)->GetFunction());
}
NODE_MODULE(native, registerModule);
推荐答案
在C ++版本中, ( result
, primeNumberCounter
, i
, j
, isPrime
,开始
,结束,
In the C++ version all variables declared in the script source (result
, primeNumberCounter
, i
, j
, isPrime
, start
, end, time
) are global because script's top level scope is global scope.
如果将源包装到立即调用函数的差异应该消失。
If you wrap the source into an immediately called function difference should go away.
这篇关于为什么V8在Node.JS比我的本地C + +插件更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!