Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 将阵列的一部分向右移动的最快方法_.net_Performance_Arrays - Fatal编程技术网

.net 将阵列的一部分向右移动的最快方法

.net 将阵列的一部分向右移动的最快方法,.net,performance,arrays,.net,Performance,Arrays,我需要在一个小数组中的给定索引处“插入”一个元素。也就是说,将索引较大的所有元素向右移动1个位置。在.NET中,最快的方法是什么 注意:我添加了我自己的答案,但我仍在寻找解释和更快的选择 编辑:我确实需要一个数组,而不是列表,也不是链表 更新:因为我没有得到奇怪性能结果的解释,所以我分别问了这个问题:有两种明显的方法:使用数组。逐个复制和复制元素: private static void ElementByElement<T>(T[] arg, int start) { fo

我需要在一个小数组中的给定索引处“插入”一个元素。也就是说,将索引较大的所有元素向右移动1个位置。在.NET中,最快的方法是什么

注意:我添加了我自己的答案,但我仍在寻找解释和更快的选择

编辑:我确实需要一个数组,而不是
列表
,也不是链表


更新:因为我没有得到奇怪性能结果的解释,所以我分别问了这个问题:

有两种明显的方法:使用
数组。逐个复制
和复制元素:

private static void ElementByElement<T>(T[] arg, int start) {
    for (int i = arg.Length - 1; i > start; i--) {
        arg[i] = arg[i - 1];
    }
}

private static T BuiltInCopy<T>(T[] arg, int start) {
    Array.Copy(arg, start, arg, start + 1, arg.Length - start - 1);
    return arg[0];            
}
以下是两次运行的结果:

f:\MyProgramming\TimSort\Benchmarks\bin\Release>Benchmarks.exe
============ Move part of array right by 1: int ============
Array.Copy()                     568475865 0:31.606 1,73
Element by element in a for loop 980013061 0:31.449 1,00

============ Move part of array right by 1: string ============
Array.Copy()                     478224336 0:31.618 2,06
Element by element in a for loop 220168237 0:30.926 4,38

============ Move part of array right by 1: DateTime ============
Array.Copy()                     382906030 0:27.870 2,27
Element by element in a for loop 458265102 0:29.239 1,99


f:\MyProgramming\TimSort\Benchmarks\bin\Release>Benchmarks.exe
============ Move part of array right by 1: int ============
Array.Copy()                     500925013 0:28.514 1,76
Element by element in a for loop 988394220 0:31.967 1,00

============ Move part of array right by 1: string ============
Array.Copy()                     483178262 0:30.048 1,92
Element by element in a for loop 193092931 0:27.642 4,43

============ Move part of array right by 1: DateTime ============
Array.Copy()                     450569361 0:30.807 2,11
Element by element in a for loop 568054290 0:31.385 1,71

也就是说,对于
int
DateTime
ElementByElement
而言,速度要快得多;而对于
string
BuiltInCopy
的速度是
ElementByElement
的两倍(对于
int
,速度是
ElementByElement
的两倍)。我希望
int
string
的结果在32位机器上非常相似,由于堆栈上对
字符串的引用与
int
的大小相同,因此除了读取和写入堆栈内存外,不应进行任何操作。

在这种情况下,使用
链表可能会更好。

首先,我想问数组是否是合适的数据结构选择这一要求。但是,我可以在您的“逐元素”复制代码中看到可能的优化:

    private static void ElementByElement2<T>(T[] arg, int start)
    {
        int i = arg.Length - 1;
        while (i > start)
            arg[i] = arg[--i];
    }
私有静态void ElementByElement2(T[]arg,int start)
{
int i=参数长度-1;
while(i>开始)
arg[i]=arg[--i];
}
我已经对此进行了基准测试,速度大约是for-loop解决方案的两倍。

列表
为例,它使用
数组。复制
,这表明如果您必须使用数组,那么这可能确实是您的最佳选择

或者,正如Indeera所指出的,使用不同的容器!根据具体用途,有些选项

  • 如果总是在0处插入,请使用
    列表
    (或者保留您自己的具有备用容量的阵列,但我想不出原因),但请反向思考-因此“插入”变为“附加”,这更便宜(尤其是在不必重新分配的情况下)
  • 链表是一个选项
  • as是队列/堆栈(取决于是否/如何删除数据)
  • 或者对于prepend和append,在两侧保留一个具有备用容量的数组,用类似于(但比)列表更复杂的东西包装,并保持偏移量-即,您有一个100的数组,并且知道您的“零”是50,您已经使用了20;然后简单地在“零”处插入更改偏移量49处的值,将主零偏移量减至49,并将虚拟长度增加至21

如果要添加到给定索引,应使用链接列表。另请参见:

除非他仍然需要随机访问,否则您可以访问链表中的任意元素,尽管这需要花费更多的时间。OP称为一个小数组。很难在1-2个缓存线内击败线性副本。我从基准测试中得到了非常不同的结果:在
int
(1,01 vs 1,00)上无法区分,在字符串上稍快(4,11 vs 4,20),在日期时间上稍慢(2,00 vs 1,70).YMMV。在我的机器上,它始终更快(英特尔至强E7730、.Net 3.5 SP1)。我只是在对一个int数组进行基准测试。也许有很多拳击比赛在进行?(使用值类型的数组比使用引用类型的数组慢…)在这种情况下,我希望
Array.Copy
on
int
string
慢,但事实并非如此。
    private static void ElementByElement2<T>(T[] arg, int start)
    {
        int i = arg.Length - 1;
        while (i > start)
            arg[i] = arg[--i];
    }