Javascript中的布尔值与整数

2022-01-19 00:00:00 performance boolean int javascript

我一直认为布尔值在存储开/关值方面比整数更有效——考虑到这是它们存在的原因.我最近决定在 jsperf 的帮助下检查这是否属实,并得出了一些相反的结果!

http://jsperf.com/bool-vs-int

这是我尝试的第一个测试.切换开/关开关的值.在 Chrome 上,使用 1/0 执行此操作要快得多,但在 Firefox 上,使用 bool 执行此操作要快一些.很有趣.

http://jsperf.com/bool-vs-int-2

这是我尝试的第二个测试.在条件中使用它们.与 bool 相比,这似乎对 int 具有显着优势,在 firefox 和 chrome 上使用 1/0 而不是 booleans 的速度提高了 70%.怎么回事?

我想我的问题是,我做错了什么吗?为什么整数在布尔的工作中表现得这么好?使用布尔值的唯一价值是清晰,还是我错过了一些重要的东西?

解决方案

免责声明,我只能说 Firefox,但我猜 Chrome 是类似的.

第一个例子(http://jsperf.com/bool-vs-int):

  1. Not 操作JägerMonkey(Spidmonkey 的 JavaScript 方法jit)首先内联检查布尔值,然后只内联异或,这非常快(我们不知道 a/b 的类型,所以我们需要检查类型).第二次检查是针对 int 的,所以如果 a/b 是 int,这会慢一些.代码p>

  2. 减法运算.我们再次不知道 c/d 的类型.再次幸运的是,我们将首先假设 int 并内联.但是因为在 JavaScript 中数字操作被指定为 IEEE 754 双精度数,所以我们需要检查溢出.因此,唯一的区别是溢出时的子"和条件跳转"与案例 1 中的普通异或.代码p>

第二个例子:(我不是 100% 确定这些,因为我以前从未真正看过这段代码)

  1. 和 3. 如果.我们内联检查布尔值,所有其他情况最终调用一个将值转换为布尔值的函数.代码p>

  2. 比较和如果.从实现的角度来看,这是一个非常复杂的案例,因为优化相等操作非常重要.所以我想我找到了正确的代码,这似乎建议我们首先检查双精度然后检查整数.因为我们知道比较的结果总是一个布尔值,所以我们可以优化 if 语句.代码p>

后续我把生成的机器码转储了,如果你还有兴趣,给你去.

总的来说,这只是大局中的一小部分.如果我们知道变量的类型并且知道减法不会溢出,那么我们可以使所有这些情况同样快.这些努力是通过 IonMonkey 或 v8 的 Crankshaft 进行的.这意味着您应该避免基于此信息进行优化,因为:

  1. 已经相当快了
  2. 引擎开发人员会为您优化它
  3. 以后会更快.

I always assumed that booleans were more efficient than ints at storing an on/off value - considering that's their reason for existence. I recently decided to check if this is true with the help of jsperf, and it came up with some contrary results!

http://jsperf.com/bool-vs-int

Here is the first test I tried. Toggling the value of the on/off switch. On Chrome it's significantly faster to do this using 1/0, but on firefox it's slightly faster to do this using bool. Interesting.

http://jsperf.com/bool-vs-int-2

And here's the second test I tried. Using them in a conditional. This appears to have significant advantage for ints as opposed to bools, up to 70% faster to use 1/0 instead of booleans - on both firefox and chrome. Wtf?

I guess my question is, am I doing something wrong? Why are ints so much better at boolean's job? Is the only value of using bools clarity, or am I missing something important?

解决方案

Disclaimer, I can only speak for Firefox, but I guess Chrome is similar.

First example (http://jsperf.com/bool-vs-int):

  1. The Not operation JägerMonkey (Spidmonkey's JavaScript methodjit) inlines the check for boolean first and then just xors, which is really fast (We don't know the type of a/b, so we need to check the type). The second check is for int, so if a/b would be a int this would be a little bit slower. Code

  2. The Subtract operation. We again don't know the type of c/d. And again you are lucky we are going to assume ints and inline that first. But because in JavaScript number operations are specified to be IEEE 754 doubles, we need to check for overflow. So the only difference is "sub" and a "conditional jump" on overflow vs. plain xor in case 1. Code

Second example: (I am not 100% sure about these, because I never really looked at this code before)

  1. and 3. The If. We inline a check for boolean, all other cases end up calling a function converting the value to a boolean. Code

  2. The Compare and If. This one is a really complex case from the implementation point of view, because it was really important to optimize equality operations. So I think I found the right code, that seems to suggest we first check for double and then for integers. And because we know that the result of a compare is always a boolean, we can optimize the if statement. Code

Followup I dumped the generated machine code, so if you are still interested, here you go.

Overall this is just a piece in a bigger picture. If we knew what kind of type the variables had and knew that the subtraction won't overflow then we could make all these cases about equally fast. These efforts are being made with IonMonkey or v8's Crankshaft. This means you should avoid optimizing based of this information, because:

  1. it's already pretty fast
  2. the engine developers take care of optimizing it for you
  3. it will be even faster in the future.

相关文章