在JavaScript中将任何字符串转换为数组的最快方式

4

我目前正在使用Javascript开发GameBoyColor模拟器。

目前将64k的ROM文件加载到内存单元需要大约60秒。这是函数:

loadROM: function (file) {
    var reader = new FileReader();

    reader.onload = function () {
        var start = new Date();
        console.log("start", start.getTime());

        this.__ROM = new Uint8Array(reader.result.length);

        for (var i = 0; i < reader.result.length; i++) {
            this.__ROM[i] = (reader.result.charCodeAt(i) & 0xFF);
        }

        var end = new Date();
        console.log("end", end.getTime());

        console.log((end.getTime() - start.getTime()) + " for " + i + " iterations");

        this._trigger("onROMLoaded");
    }.context(this);

    reader.readAsBinaryString(file);
}

reader.result 是ROM文件的字符串形式,this.__rom是数组。重要的是for循环,在该循环中,我获取每个单独的字符并将其推入内存的ROM数组中。

这需要太长时间。那么问题是如何加速这个过程。是否有更好的方法将字符串转换为数组?


既然你需要一个数组,为什么不使用 readAsArrayBuffer? - GameAlchemist
因为我需要它以二进制格式。 - Johannes Klauß
ArrayBuffer会提供与读取字符串和转换相同的结果,只是速度更快。 - GameAlchemist
但这正是readAsArrayBuffer将为您提供的内容。代码:this.__ROM = new UInt8Array(reader.result); 就这样结束了。 - GameAlchemist
你有检查过 任何 值是否 > 0xFF 吗?我猜没有,所以实际上你只需要复制,不需要掩码。此外,字符串可以接受数组表示法 myString[i],无需使用 charCodeAt。缓存你的数组和数组长度。- 并尝试使用 readAsArrayBuffer :-) - - GameAlchemist
1个回答

5

您应该可以直接使用split()来代替循环进行操作:

// See the delimiter used
this.__ROM = reader.result.split('');

// And to do the bitwise AND on each byte, use map()
this.__ROM = this.__ROM.map(function(i) {
    return i & 0xFF;
});

或者一步完成(不需要两次写入this.__ROM):

this.__ROM = reader.result.split('').map(function(i) {
    return i & 0xFF;
});

事情是,我忘了什么。我仍然需要访问每个字符,因为我需要将每个字符作用域限定为0xFF。 - Johannes Klauß
@JohannesKlauß - 我也添加了一个解决方案。然而,速度提升主要是因为本地实现的分割方法。 - techfoobar
哇... 这真的是超级快速!非常感谢。 - Johannes Klauß
@techfoobar:在称之为“速度提升”之前,我要求看到两种方法的基准测试结果。 :) 如果map和内联函数的开销完全消除了split()方法的增益,我不会感到惊讶。虽然我认为现代JS解释器会对其进行JIT编译。 - haylem
@JohannesKlauß - 如果你想再节省几毫秒,可以这样做:this.__ROM = reader.result.split('').map(function(i) { return i & 0xFF; }); - 这样我们就不必两次写入this.__ROM了 :-) - techfoobar
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接