Aha*_*ebi 0 javascript for-loop v8 slowdown
我试图对 javascript 和 .net core 进行基准测试,以便选择一个服务器端框架来提供一些需要迭代大型数组(大约 21 亿)的特定 Restful 服务。在处理一个简单的代码时,我意识到 node 在特定的数字迭代后有奇怪的行为。我在多个平台上重复并达到了相同的结果。测试平台为:
运行视频显示出人意料地将处理时间从 300 毫秒增加到 600 毫秒大约两倍
var cnt = 0;
var logPeriod=100000000;
var max=10000000000;
for (let i = 0; i < max; i++) {
if (i % logPeriod === 0) {
// var end = Date.now();
if (i !== 0) {
console.timeEnd(cnt*logPeriod, i);
cnt++;
}
console.time(cnt*logPeriod);
}
}Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<script>
function doloop() {
var cnt = 0;
var logPeriod = 100000000;
var max = 10000000000;
for (let i = 0; i < max; i++) {
if (i % logPeriod === 0) {
// var end = Date.now();
if (i !== 0) {
console.timeEnd(cnt * logPeriod, i);
cnt++;
}
console.time(cnt * logPeriod);
}
}
}
</script>
</head>
<body>
<button onclick="doloop()">doloop</button>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
V8 开发人员在这里。
V8 的优化编译器生成的代码尽可能使用纯 32 位整数作为数字。一旦一个数字超过 int32 范围(或精度要求,即当它需要保存小数值时),那么这种优化的代码将被丢弃(或从不首先生成)并使用 64 位双精度值,作为 JavaScript 规范需要。算术运算(即使是像 一样简单的东西i++)在 64 位双精度上比在 32 位整数上慢,这正是硬件所做的。
在行为方面,这种内部差异是无法观察到的:数字总是表现得好像它们是 64 位双精度数。但这并不意味着引擎实际上总是在引擎盖下使用 64 位双精度数:正如您在此处看到的,当引擎可以在内部使用 32 位整数时,会带来显着的性能优势。
选择 [JavaScript or .net for] 需要迭代大型数组(约 21 亿)的 restful 服务
这是一个简单的决定:使用 .net。V8(以及 Node)不允许您创建包含 21 亿个元素的数组,因为每个对象的大小限制远低于此限制。当然,var a = new Array(2_100_000_000)会评估得很好,但那是因为它实际上并没有分配所有的内存。开始填充元素并在一段时间后观看它崩溃:-)
如果您的实际阵列毕竟不会那么大,那么请定义一个更接近您实际工作负载的基准,因为它的结果将更具代表性,因此对您的决策更有用。
| 归档时间: |
|
| 查看次数: |
143 次 |
| 最近记录: |