【问题标题】:Which way of storing and operating on bitfields in javascript is the fastest? (200k+ bits)javascript中哪种存储和操作位域的方式最快? (200k+ 位)
【发布时间】:2012-12-26 20:40:16
【问题描述】:

我正在分析我打算在 Android (PhoneGap) 上的嵌入式浏览器上使用的 javascript 代码。

基本上我需要一个非常大的位域(200k+ 位)来进行计算。

我尝试将它们放入无符号整数数组中,每个项目存储 32 位 - 这确实减少了内存使用,但大大 太慢了(简单的迭代和反转超过 30 秒现代 PC 上位域中的所有位!)

比我制作的老式布尔数组更好。这增加了内存使用量(但我的代码周围的整个 PhoneGap 框架在 Android 上仍然不到 15 兆)。分析向我展示了我算法的初始步骤 - 将位域的所有元素设置为 1(简单的 for 循环) - 需要一半的执行时间(在 PC 上约为 1.5 秒,在 Android 上超过几分钟)。我可以重写我的代码,所以默认值是 0 而不是 1(反转所有条件),但我仍然不知道如何将这么大的数组快速设置为 0。

编辑按要求添加我的代码:

var count = 200000;
var myArr = [];

myArr.length = count;
for(var i = 0; i < count ; i++)
    myArr[i] = true;

有人可以指出我如何清除非常大的数组,或者有没有更快的方法来存储和操作 javascript 中的大型位域?

【问题讨论】:

  • Bitfields ... Javascript ... 快速 ... 问:我是唯一一个在这里看到多重矛盾的人吗?)?
  • 您介意发布代码吗?
  • PiotrK,试试 Typed Arrays:khronos.org/registry/typedarray/specs/latest - 这是 Bellard 的 JS x86 模拟器的选择:bellard.org/jslinux/tech.html;从 4.0 开始支持 caniuse.com/typedarrays
  • @paulsm4 我只看到一个矛盾,三方面的且不明显。 javascript 中的位域是可能的。快速位域是可能的。快速的 javascript 是可能的。这里唯一不明显的是如何在 Javascript 中制作快速位域。
  • 在您的所有计算中是否不可能将undefined 值视为true?这样您就可以完全跳过初始化阶段。

标签: javascript cordova bit-manipulation bit-fields


【解决方案1】:

看看这是否是一种更快的创建数组的方法:

var myArray = [true];
var desiredLength = 200000;
while (myArray.length < desiredLength) {
    myArray = myArray.concat(myArray);
}
if (myArray.length > desiredLength) {
    myArray.splice(desiredLength);
}

I've added a few more test cases to the jsperf page that Asad linked in his comment。到目前为止,我的浏览器(Mac OS X 10.8.2 上的 Chrome 23.0.1271.101)中最快的是这个:

var count = 200000;
var myArr = [];
for (var i = 0; i < count; i++) {
  myArr.push(true);
}

【讨论】:

  • 哇,真是个好主意 - 不幸的是它不能很好地工作,它在我的 PC 上比简单的数组迭代器慢 10 倍(我已经运行了这两种方法 50 次)
  • @Asad 这取决于你的 JavaScript 实现。在我的浏览器(Mac OS X 10.8.2 上的 Chrome 23.0.1271.101)中,concat 版本每秒执行的操作数大约是“普通”版本的两倍。真正重要的是每个版本在 Android 上的 phonegap 中的速度有多快。我没有任何 Android 设备可供测试。我已将a few more test cases 添加到您的帐户中。
  • 在我的系统上测试,它在 Chrome 中快 3 倍,在 FF 中慢 8 倍,在 IE 中慢 3 倍(比 op 的方法)。
  • @robmayoff 我测试了push 方法,但在FF 中它慢了一倍,所以我放弃了。非常奇怪的是,不同 JS 实现的结果差异如此之大,尤其是因为我希望底层算法是相同的。
  • 在 Android 4.0 上添加了 Chrome 18
【解决方案2】:

为什么首先要预先填充数组!使用undefined 对您有利。请记住,未定义充当 falsey 值。因此,当您进行布尔检查时,它的行为与 0/false 完全相同。

var myArray = new Array(200000);

if (myArray[1]) {   
  //I am a truthy value
} else {
  //I am a falsey value
}

所以当你以这种方式初始化数组时,没有理由预填充!这意味着无需额外处理并利用稀疏数组!

【讨论】:

    猜你喜欢
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    相关资源
    最近更新 更多