You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript整数与小数运算速度差异:局部/全局变量为何表现不同?

局部变量vs全局变量:整数与小数运算的性能差异解析

测试代码

// 局部变量测试
(function() { 
  var i, x; 
  console.time('a'); 
  for (i = x = 0; i < 1000000; x++) { 
    if (x > 1000) { 
      i++; 
      x = 0; 
    } 
  } 
  console.timeEnd('a'); 

  console.time('b'); 
  for (i = x = 0; i < 1000000; x += 0.001) { 
    if (x > 1) { 
      i++; 
      x = 0; 
    } 
  } 
  console.timeEnd('b'); 
})();

// 全局变量测试
var i, x; 
console.time('c'); 
for (i = x = 0; i < 1000000; x++) { 
  if (x > 1000) { 
    i++; 
    x = 0; 
  } 
} 
console.timeEnd('c'); 

console.time('d'); 
for (i = x = 0; i < 1000000; x += 0.001) { 
  if (x > 1) { 
    i++; 
    x = 0; 
  } 
} 
console.timeEnd('d');

测试结果

  • 局部变量组:a(整数运算)耗时约1200ms,b(小数运算)耗时约1200ms,两者性能几乎无差异
  • 全局变量组:c(整数运算)耗时约2300ms,d(小数运算)耗时约23000ms,d的速度比c慢了整整10倍

核心疑问

我理解局部变量因查找范围窄更快,但无法理解为何局部变量时整数与小数运算速度无差,全局变量时却差异巨大?


这是个非常有意思的性能观察!背后的核心原因在于JS引擎对局部变量和全局变量的优化策略完全不同:

1. 局部变量:封闭作用域带来的深度优化

以主流的V8引擎为例,局部变量的优势不止是查找范围窄:

  • 局部变量存储在函数的栈帧中,引擎可以通过固定内存偏移量直接访问,不需要像全局变量那样去遍历对象属性链。
  • 更关键的是,封闭的函数作用域让引擎能精准跟踪变量的类型变化。比如测试b中,x虽然在整数(0)和浮点数之间切换,但引擎能预测到这种循环模式,直接生成优化后的机器码——甚至会把变量放到CPU寄存器中运算,把类型转换的开销降到可以忽略的程度。

2. 全局变量:开放性与类型波动击穿优化机制

全局变量挂载在全局对象(浏览器中是window)上,引擎对它的优化难度大很多:

  • 全局对象是动态可变的,引擎无法保证x不会被外部代码修改,因此很难维持稳定的缓存优化。
  • 测试d中的全局变量x频繁在小整数(Smi,V8对小整数的特殊优化存储)和堆浮点数(Heap Number)之间切换。每次类型切换都会导致引擎的内联缓存(IC)失效——原本为快速访问属性建立的缓存不再适用,引擎不得不退回到慢路径,每次读写x都要重新检查类型、查找属性,这直接把浮点数运算的开销放大了数倍。
  • 而测试c中的全局变量x始终是整数类型,引擎能维持稳定的内联缓存,所以虽然比局部变量慢,但性能下降幅度远不如d。

简单总结:局部变量的封闭性让引擎可以大胆做深度优化,哪怕类型有规律切换也能高效处理;而全局变量的开放性加上类型频繁波动,直接击穿了引擎的优化机制,导致小数运算的开销被急剧放大。

内容的提问来源于stack exchange,提问作者msm082919

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:50:04