2017-09-20 41 views
1

我有一个来源Float32Array,我从中创建了一个辅助Float32Array。我有一个值为model的序列,我想将其作为重复序列复制到第Float32Array。我目前正在使用reverse while循环执行此操作。更有效的方法将重复序列复制到TypedArray中?

sequence = [1, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, 0]; 
n = 3179520; //divisible by sequence length 
modelBuffs = new Float32Array(n); 

var v = modelBuffs.length; 

while(v-=12){ 
    modelBuffs[v-12] = sequence[0]; 
    modelBuffs[v-11] = sequence[1]; 
    modelBuffs[v-10] = sequence[2]; 
    modelBuffs[v-9] = sequence[3]; 

    // YTransform 
    modelBuffs[v-8] = sequence[4]; 
    modelBuffs[v-7] = sequence[5]; 
    modelBuffs[v-6] = sequence[6]; 
    modelBuffs[v-5] = sequence[7]; 

    // ZTransform 
    modelBuffs[v-4] = sequence[8]; 
    modelBuffs[v-3] = sequence[9]; 
    modelBuffs[v-2] = sequence[10]; 
    modelBuffs[v-1] = sequence[11]; 
} 

不幸的是,n可能未知。如果没有其他解决方案,我可能不得不做一个重要的重构。我希望我可以设置序列一次,并有一个复制到位/重复填充/按位操作重复的初始字节序列。

编辑简化了示例输入

+0

正如我所看到的,你有一个模式,但你没有使用'3,7,11,15'的值。任何具体原因? – Rajesh

+0

@rajesh我从一个更多涉及的例子中截取了这个。具体原因是3,7,11,15是未使用的4×4矩阵的最后一列 – kevzettler

+0

因此,我们应该假设在'N×M'矩阵中,总是不使用'm-1'列? – Rajesh

回答

2

一种快速方法来填充的阵列与重复序列,是加倍缓冲器的长度用于使用所述类型数组的copyWithin()方法每次迭代。您可以使用set()以及为相同的底层ArrayBuffer创建不同的视图,但为此使用前者更为简单。

使用例如1234作为源,第一初始迭代填充将是1:1,或4索引在这种情况下:

1234 

从那里,我们将使用目标缓冲区作为源对于其余的填充所以第二次迭代填充8个索引:

12341234 

第三次迭代填充16个指数:

1234123412341234 

第四次迭代填充32个指数:

12341234123412341234123412341234 

等等。

如果最后一个段的长度与2的幂不匹配,可以简单地在最后一个填充和剩余在缓冲区中的长度之间做一个差异,并将其用于最后一次迭代。

如果数组是很长的它显然需要一些时间不管。在这些情况下,您可以考虑将Web Worker与新的SharedArrayBuffer结合使用,以便您可以在不同的进程中进行复制,而不必复制或传输数据。从这里获得的收益仅仅是主线程不会受到处理缓冲区的小开销的阻碍,因为copyWithin()的内部对于其目的已经是相对最佳的。缺点是异步方面与事件系统的开销相结合(例如:这取决于这是否有用)。

一个不同的方法是使用WebAssembly在C/C++中编写缓冲区填充代码,编译和公开方法来获取源缓冲区和目标缓冲区,然后从JavaScript调用它。这种情况我没有任何例子。

在这两种情况下,您都会遇到(不是那么多)旧版浏览器的兼容性问题。

+0

这是非常好的谢谢! – kevzettler