为什么我的C ++插件中的Google V8 JavaScript引擎比Node.JS的运行速度明显慢?
我试图编写一些愚蠢的简单代码来在JavaScript中生成素数,并通过C ++插件在V8中直接在Node.JS中运行它。
我很震惊,因为两个都应该使用相同的JavaScript引擎并且都执行了相同的代码(时间以毫秒为单位,时间越短越好):
V8 in Node.JS: 495517
V8 in Node.JS C++ Addon: 623598
这是运行相同JavaScript代码的JavaScript模块和C ++插件的源(我认为问题不在互操作中,因为时间的测量直接在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
,start
,结束time
)是
全球 因为脚本的顶层作用域是全局范围。
为了优化编译器,很容易将局部变量分配到机器寄存器(或堆栈中的溢出槽)并跟踪其类型。另一方面,使用全局变量需要持续的内存访问和类型检查,因为V8当前(当前)不执行寄存器提升优化。
如果将源包装为立即调用的函数,则差异会消失。
问题内容: 阅读此内容后,引人注目: BSON还被设计为快速编码和解码。例如,整数存储为32(或64)位整数,因此不需要在文本之间进行解析。对于小整数,此方法比JSON使用更多的空间, 但解析速度要快得多 。 根据我的阅读,使用BSON的全部目的是因为它对CPU的负担更少,并且编码/处理速度更快。 但是,我对Node.js进行了一些测试,并使用本机JSON方法使BSON脱颖而出。一些测试表明J
问题内容: 为了在工作中进行演示,我想比较NodeJS和C的性能。这是我写的: Node.js(for.js): 我使用GCC编译for.c并运行它: 结果: 然后我在NodeJS中尝试了它: 结果: 在运行了无数次之后,我发现无论如何它都是成立的。如果我将for.c切换double为long在循环中使用a而不是a ,则C花费的时间甚至更长! 不是试图发动火焰战争,但是为什么执行相同操作的Node
如果我GZip这个文本: 你好,世界 通过C#使用此代码: 生成的流长度为133字节 通过Fiddler的或此PHP页面,结果只有31字节长。 在这两种情况下,输入都是11字节,因此我认为PHP结果是正确的,但显然这意味着我无法从内部解压缩PHP zip。NET或visa反之亦然。为什么会这样。净产出如此之大? 事实证明,虽然PHP和Fiddler的结果是相同的长度,但它们并不相同。我可以在中解压
问题内容: 下面是分别用和编码的简单过程(对于那些对此过程感到好奇的人,这是针对Euler项目5号问题的解决方案)。 我的问题是,下面的代码仅需9秒即可迭代,而代码完成则需要283秒(确切地说,在Python 3.4.3-64位上为283秒,在Python 2.7.9-32位上为329秒)。 到目前为止,我已经编码的两种类似的过程和与执行时间的差异,具有可比性。但是,这次,经过的时间之间存在极大的
问题内容: 我考虑这个问题已有一段时间了,似乎找不到答案。Node.js和V8有什么关系?可以在没有V8的情况下使用Node.js吗? 问题答案: Node.js和V8有什么关系? V8是node.js内的Javascript引擎,用于解析和运行Javascript。Chrome内部使用了相同的V8引擎,以在Chrome浏览器中运行javascript。Google开源了V8引擎,node.js的
因此,我已经阅读了大约半年的关于x86处理器内部发生的事情。所以我决定尝试一下x86程序集的乐趣,只从80386指令开始,以保持它的简单性。(我主要是在学习,而不是优化) 几个月前我做了一个用C语言编写的游戏,所以我去那里用汇编代码从头重写了位图blitting函数。我不明白的是,循环的主要像素绘制主体使用C代码(18条指令)比我的汇编代码(只有7条指令,我几乎100%确定它不会跨越缓存行边界)更