在像C++/Java/C#等语言中使用位运算符的主要理念之一是它们非常快速。但我听说在JavaScript中,它们很慢(尽管几毫秒可能今天无关紧要)。为什么会这样?
(这个问题讨论了何时使用位运算符,因此我将此问题的重点转移到性能方面。)
在像C++/Java/C#等语言中使用位运算符的主要理念之一是它们非常快速。但我听说在JavaScript中,它们很慢(尽管几毫秒可能今天无关紧要)。为什么会这样?
(这个问题讨论了何时使用位运算符,因此我将此问题的重点转移到性能方面。)
这是一个相当古老的问题,但似乎没有人回答更新版本。
JavaScript中存在的性能损失,在C/C++中是不存在的。这是由于将浮点数表示法(JavaScript存储所有数字的方式)转换为32位整数进行位操作及还原。
现在没人再使用十六进制了吗?
function hextoRgb(c) {
c = '0x' + c.substring(1);
return [(c >> 16) & 255, (c >> 8) & 255, c & 255];
}
var c1 = hextoRgb('#191970');
alert('rgb(' + c1.join(',') + ')');
return /#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i.exec(c).slice(1).map(function(e) {return parseInt(e, 16);});
- Robert我在JS中使用零位移操作进行快速整数截断:
var i=3.141532;
var iTrunc=i>>0; //3
何时需要使用它们?当您想执行位运算时,您会想要使用它们。就像您使用布尔运算符执行布尔运算一样,使用数学运算符执行数学运算一样。
如果您熟悉位运算符,则在某些应用程序中使用它们非常自然。它们可以用于许多其他目的,而不仅仅是超优化的布尔数组。当然,在JavaScript编程中很少遇到这些情况,但这并不是运算符不应该可用的原因。
我认为操作符的效率高低取决于实现者。例如,没有任何东西可以阻止JavaScript实现者制作一个即时编译虚拟机,将位运算转化为一条机器指令。因此,“JavaScript中的位运算符”本身并不慢。
让我们仍然考虑某些特定原因导致JavaScript主机的各种实现者以使这些操作极其缓慢的方式实现位运算,并看看这是否重要...
尽管JavaScript已用于其他目的,但此语言最常见的用途是提供用户界面类型的服务。
顺便说一句,我绝不是以任何贬义的方式表达这个意思;执行这些智能UI功能,并考虑到对语言施加的各种限制以及对标准的松散遵守,需要-并且仍然需要-有才华的JavaScript黑客。
关键是,在UI类型需求的背景下,需要进行任何可能暴露JavaScript处理此类操作的缓慢性的大量位运算的需求最多也只是偶尔发生。因此,对于典型的用途,程序员应该在整体程序/数据流与位运算方法相符的情况下使用位运算,并且他们应该很少关注性能问题。在位运算使用引起性能瓶颈的不太可能的情况下,可以重新设计事物,但最好避免过早优化。
上述规则的一个显著例外是引入画布。在现代浏览器上,我们可以预期JavaScript主机将需要更多原始图形函数,而这些操作在某些情况下可能需要大量的位运算(以及大量的数学函数)。这些服务很可能最终会通过JavaScript库的方式得到支持(甚至成为语言附加组件)。对于这样的库,行业智慧将被利用来找出最有效的方法。此外,如果确实存在JavaScript性能在位运算方面的弱点,我们将得到一些帮助,因为我预测各种主机(浏览器)上的JavaScript实现将被修改以改进此特定领域。(这将遵循多年来我们所看到的JavaScript演变的典型模式。)
在Windows脚本宿主JScript中使用JavaScript,您可能需要使用位运算符从WMI或Active Directory调用返回的值中选择标志。例如,AD中用户记录的用户访问值包含打包到一个长整数中的多个标志。
ADS_UF_ACCOUNTDISABLE = 0x00000002;
if (uac & ADS_UF_ACCOUNTDISABLE == ADS_UF_ACCOUNTDISABLE) {
// user account has been disabled
}
或者某人的任意表结构可能包含这样一个字段,可以通过JScript中的ADO访问。
或者您可能希望将检索到的一些数据转换为任何平台上的二进制表示,仅仅因为:
BinaryData = "L";
BinaryString = BinToStr(BinaryData, ".", "x");
// BinaryString => '.x..xx..'
因此,有许多原因为什么人们想在JavaScript中进行位操作。就性能而言,唯一的方法是编写并测试它。我怀疑在大多数情况下,它将是完全可接受的,不会比这些系统包含的其他众多低效率方式更糟糕。
当速度至关重要时,您可以使用它们进行位掩码:http://snook.ca/archives/javascript/storing_values/
此外,如果您需要支持Netscape 4,您将使用它们来处理Document.captureEvents()。并不是任何值得尊敬的公司都会让您为NS4编写JS...