Javascript 告诉JS我在使用数字的方法(优化)
当看到Javascript 告诉JS我在使用数字的方法(优化),javascript,optimization,bitwise-operators,Javascript,Optimization,Bitwise Operators,当看到+介于两件事之间时,JS似乎会抓狂。不知道类型,因此必须找到类型。我遇到了世卫组织的例子: x = x | 0; y = y | 0; 告诉JS我们正在使用数字。我需要bit解释它在引擎盖下是如何工作的,或者至少用外行的话说 如果这是告诉JSx和y是数字的方法,那么我们如何告诉JS变量是字符串,布尔值等等。。。使用此按位运算符。还有,为什么在日常应用程序中不经常使用它呢?我想如果你在这个网站上搜索,你会发现很多关于铸造数字和特殊类型的javascript的信息 就个人而言,我不喜欢按位或
+
介于两件事之间时,JS似乎会抓狂。不知道类型,因此必须找到类型。我遇到了世卫组织的例子:
x = x | 0;
y = y | 0;
告诉JS我们正在使用数字。我需要bit
解释它在引擎盖下是如何工作的,或者至少用外行的话说
如果这是告诉JS
x
和y
是数字的方法,那么我们如何告诉JS变量是字符串
,布尔值
等等。。。使用此按位运算符。还有,为什么在日常应用程序中不经常使用它呢?我想如果你在这个网站上搜索,你会发现很多关于铸造数字和特殊类型的javascript的信息
就个人而言,我不喜欢按位或
的公式。有几个原因,但主要是因为它似乎是一个容易发现难以检测的bug的地方。考虑到发布的视频中的功能,请考虑:
函数添加(x,y){
x=x | 0
y=y | 0
返回x+y
}
console.log(添加(1,无穷大))
// 1? 这不应该是不有限的吗?
console.log(添加(无限,无限))
// 0? 这不应该是不有限的吗?
log(添加(1,{n:4}))
// 1? 南似乎更合理
console.log(添加(1,未定义))
// 1? NaN似乎更合理
您发布的代码片段位于一张名为“asm.js”的幻灯片上,是一个更大示例的一部分:
function Module() {
"use asm";
function add(x, y) {
x = x | 0;
y = y | 0;
return x + y;
}
return {add: add};
}
请注意“use asm”
注释-Mozilla引入该注释是为了让JS引擎知道此代码旨在符合,它定义了JavaScript的受限子集,可以使用“提前”编译器将其编译成高效的机器代码
旁白:自2013年引入asm.js以来,浏览器供应商已经达成一致,这是一个新标准,它在不使用奇怪的JavaScript语法的情况下解决了同样的问题。
常规JavaScript具有,这意味着您可以编写函数add(x,y){return x+y;}
,然后将其与不同类型的参数一起使用,如:
add(1,2) /* =3 */
add("Hello ", "world") /* ="Hello world" */
// or even
add("1+1=",2) /* ="1+1=2" */
正因为如此,JS引擎无法“提前”为函数生成有效的代码——在它看到如何使用它之前:它需要考虑传递给它的任何可能类型的参数
出现此问题的JS引擎是:
- 缓慢启动-通过生成字节码并通过解释器运行它,同时观察变量的实际类型
- 当代码的某些部分变得“更热”(即重复运行)时,它们会更积极地使用在步骤1推断的类型重新编译(“及时”)
- 由于推断的类型不能保证保持不变(例如,您可以调用
100000次,然后调用add(int,int)
,因此优化的代码必须对此进行防范——如果发生这种情况,则返回较慢的模式add(string,string)
a=a | 0
语法背后的想法是,他们不想发明一种新语法,因为这会阻止使用新语法的代码在不支持它的浏览器中运行。因此,他们使用这种结构,这种结构已经将任何JS引擎中的输入值强制为符合规范的整数,让支持ort asm.js知道变量的类型
如果这是告诉JS x和y是数字的方法,我们如何告诉JS变量是字符串、布尔等…使用这个位运算符
asm.js,因为C中的字符串只是指向存储字符串各个字节的内存块的指针(即整数索引)。EmScripten编译的代码不使用JavaScript
string
s。
生成32位整数……这可能没问题,但如果使用的数字是a,则会把事情搞砸。)非整数,或b)在32位(有符号?)整数范围之外,大约+/-20亿警报(+“5”+“7”)代码>或警报(“5”-“7”)代码>或警报(“5”*1+“7”*1)代码>以及我是否应该在每次添加两个数字时使用例如Number(x)+Number(c)?这会提高脚本的性能吗?我怀疑它会提高性能,但我从未测试过它。除非真的有必要,否则我很少看到JS代码带有显式强制。我认为大多数JS已经学会了接受弱类型并享受灵活性。那些需要强类型的函数使用Typescript。|0
技巧的要点是指出函数需要(并且您承诺提供)一个整数,而不是JS数字或任何其他类型。添加两个整数是一条机器指令,而添加两个JSNumber
s必须考虑更多的可能性:浮点、无穷大、NaN
、-0
等等。@Learnonhardway:你不应该使用Number(x)+Number(c)
,相反,确保x
和c
具有稳定的类型:例如整数。这可以让JS引擎优化函数,但与类型不一致会严重影响性能。@Nickolay我理解-我对这个问题的解释是“这是告诉JS x和y是数字的方式吗?”有时,显式转换一个数字很重要,但这不是做这件事的方法。在那里读的好文章。在我读过这篇文章之后,可能会回到这篇文章。另外,VarA=Number(3)比VarA=3好吗?如果