告诉JS即时通讯使用NUMBERS(优化)

时间:2017-11-12 06:13:13

标签: javascript optimization bitwise-operators

看起来像JS在两件事之间看到+时吓坏了。不知道类型,所以它必须找到类型。我遇到了this guy (video with time stamp)的例子:

x = x | 0;
y = y | 0;

告诉JS我们正在使用数字。我需要bit解释它是如何运作的,或者至少是外行人的术语。

如果这是告诉JS xy是数字的方法,我们如何告诉JS变量是stringsbools等...使用这个按位运算符。另外,为什么在日常应用中不经常使用它?

2 个答案:

答案 0 :(得分:1)

您发布的代码段位于名为“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引擎知道这段代码是为了符合asm.js specification,它定义了一个受限制的JavaScript子集,可以使用“提前”编译器编译成高效的机器代码。

除此之外:自2013年asm.js推出以来,浏览器供应商一致同意WebAssembly,这是一种新标准,可以在不使用奇怪的JavaScript语法的情况下解决同样的问题。

常规JavaScript有dynamic typing,这意味着您可以编写function 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引擎无法“提前”生成函数的高效代码 - 在它看到它的使用方式之前:它需要考虑传递给它的任何可能类型的参数。

带有此问题的

The way JS引擎deal是:

  • 开始慢 - 通过生成字节码并通过解释器运行它,同时观察变量实际具有的类型
  • 由于代码的某些部分变得“更热”(即重复运行),因此在步骤1中使用推断的类型更积极地重新编译它们(“及时”)
  • 因为推断的类型不能保证保持不变(例如,你可以调用add(int, int) 100000次然后调用add(string, string),优化的代码必须有防范这一点 - 然后再回到如果发生这种情况,速度较慢的模式。

这是一种相当智能的技术,它通常适用于手写JavaScript,但它显然比编译静态类型代码(如C编译器那样)有更多的开销。如果您有一个C(++)代码库(通过使用EmScripten将其编译为JavaScript,则在浏览器中运行) - 例如,Unreal Enginechess engine,{{3}等等 - 你可以比这更好。

这就是Mozilla提出asm.js的原因:C-to-JS编译器可以在生成的JS中嵌入类型注释,并允许JS引擎从一开始就有效地编译它。

a = a | 0语法背后的想法是他们不想发明新语法,因为这会阻止使用新语法的代码在不支持它的浏览器中运行。所以他们使用这个构造,它已经将任何输入值强制转换为遵循规范的任何JS引擎中的整数,以使支持asm.js的引擎知道变量的类型。

  

如果这是告诉JS x和y是数字的方法,我们如何告诉JS变量是字符串,bool等...使用这个按位运算符

asm.js DOS emulator,因为C中的字符串只是指向保存字符串各个字节的内存块的指针(即整数索引)。 EmScripten编译的代码不使用JavaScript String s。

答案 1 :(得分:0)

我认为如果你在这个网站上搜索,你会发现很多关于投射数字和javascript的特殊输入。

就个人而言,我不喜欢按位or的配方。有几个原因,但主要是因为它似乎是一个容易找到难以检测的错误的地方。鉴于发布的视频中的功能,请考虑:



function add(x, y) {
  x = x | 0
  y = y | 0
  return x + y
}

console.log( add(1, Infinity) )
// 1? Shouldn't that be inifinity?

console.log( add(Infinity, Infinity) )
// 0? Shouldn't that be inifinity?

console.log( add(1, {n: 4}) )
// 1? NaN seems more reasonable

console.log( add(1, undefined) )
// 1? NaN seems more reasonable




现代JS还有其他方法可以用更合理的行为来强制数字,例如Number()



function add(x, y) {
      x = Number(x)
      y = Number(y)
      return x + y
    }
    
console.log( add(2, Infinity) )
// Infinity

console.log( add(1, {m: 2}) )
// NaN

console.log( add(1, "2") )
// 3 - still casts strings as expected

console.log( add(1, [2]) )
// 3 - and single element array




有关Number() vs parseInt()的一件事值得一提:



console.log(parseInt("24px", 10))
// 24 - handy for browser work

console.log(Number("24px"))
// Nan - stricter




其他类型(String(23)Boolean(1)等也有类似的功能。)