如何在C#中加速数组克隆?

11
我正在解决绑定变量崇拜问题。该问题的一部分要求你实现一个“古老”的通用机器的解释器。我已经实现了他们描述的机器的解释器,现在正在运行大学提供的基准测试程序进行测试。我的这个解释器的C#实现非常缓慢!我使用ANTS性能分析器启动了我的程序,以查看减速在哪里,我可以看到超过96%的时间都被“加载程序”操作占用。

ANTS Profile Results

这个操作符的specification如下:
 #12. Load Program.

              The array identified by the B register is duplicated
              and the duplicate shall replace the '0' array,
              regardless of size. The execution finger is placed
              to indicate the platter of this array that is
              described by the offset given in C, where the value
              0 denotes the first platter, 1 the second, et
              cetera.

              The '0' array shall be the most sublime choice for
              loading, and shall be handled with the utmost
              velocity.

这是我为这个运算符编写的代码:
case 12: // Load Program
    _platters[0] = (UInt32[])_platters[(int)_registers[B]].Clone();
    _finger = _registers[C];
    break;

整个“通用机器”解释器的源代码在这里

我应该怎么做才能让它更快?有其他用C编写的实现,可以显著更快地完成整个基准测试。


1
你能为 _platters 和其他成员提供类型吗?尝试使用 Array.Copy、Buffer.BlockCopy 或指针。 - Lukasz Madon
@lukas,我提供了一个链接到Github页面,其中包含整个类。但是_platters是一个List<UInt32>。 - mmcdole
好奇一下,使用被接受的答案后速度提升了多少?这样你的问题对其他 Stack Overflow 用户会更有价值。 - sehe
5个回答

7

您可以尝试使用Buffer.BlockCopy,但我对此是否能在这种情况下有很大的区别感到惊讶:

case 12: // Load Program
    uint[] src = _platters[(int)_registers[B]];
    _platters[0] = new uint[src.Length];
    Buffer.BlockCopy(src, 0, _platters[0], 0, src.Length * 4);
    _finger = _registers[C];
    break;

7

4

看起来Anton刚刚发了帖子,但是比我快。 :-) - Ed Bayiates

0

根据两个结果数组的使用方式,您可以使用修改后的写时复制:

您不会直接使用数组,而是使用包装器。要克隆数组,只需创建另一个包装器。如果您尝试写入由多个包装器共享的数组,则执行实际克隆并解除包装器之间的耦合。


0

除了手头的问题,你的虚拟机性能表现不佳的真正原因是你应该像规范中所说的那样,以最高速度处理0;)

基本上,常规跳转是通过从0到0进行加载来执行的。这在代码中非常常见。在特定情况下,你应该完全避免克隆,只更新“指针”。


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