gpt4 book ai didi

c# - 将二维数组转换为列表(一维)的快速方法

转载 作者:IT王子 更新时间:2023-10-29 04:25:20 29 4
gpt4 key购买 nike

我有一个二维数组,我需要将它转换为一个列表(同一对象)。我不想使用 forforeach 循环来执行此操作,它们将获取每个元素并将其添加到列表中。还有其他方法吗?

最佳答案

好吧,你可以让它使用“blit”类型的副本,尽管这确实意味着要制作一个额外的副本:(

double[] tmp = new double[array.GetLength(0) * array.GetLength(1)];    
Buffer.BlockCopy(array, 0, tmp, 0, tmp.Length * sizeof(double));
List<double> list = new List<double>(tmp);

当然,如果您对一维数组感到满意,请忽略最后一行:)

Buffer.BlockCopy作为 native 方法实现,我期望在验证后使用极其高效的复制。 List<T> constructor它接受 IEnumerable<T>针对实现 IList<T> 的情况进行了优化, 作为 double[]做。它将创建一个大小合适的后备数组,并要求它将自身复制到该数组中。希望那会使用 Buffer.BlockCopy或类似的东西。

这是三种方法(for 循环、Cast<double>().ToList() 和 Buffer.BlockCopy)的快速基准测试:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

class Program
{
static void Main(string[] args)
{
double[,] source = new double[1000, 1000];
int iterations = 1000;

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
UsingCast(source);
}
sw.Stop();
Console.WriteLine("LINQ: {0}", sw.ElapsedMilliseconds);

GC.Collect();
GC.WaitForPendingFinalizers();

sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
UsingForLoop(source);
}
sw.Stop();
Console.WriteLine("For loop: {0}", sw.ElapsedMilliseconds);

GC.Collect();
GC.WaitForPendingFinalizers();

sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
UsingBlockCopy(source);
}
sw.Stop();
Console.WriteLine("Block copy: {0}", sw.ElapsedMilliseconds);
}


static List<double> UsingCast(double[,] array)
{
return array.Cast<double>().ToList();
}

static List<double> UsingForLoop(double[,] array)
{
int width = array.GetLength(0);
int height = array.GetLength(1);
List<double> ret = new List<double>(width * height);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
ret.Add(array[i, j]);
}
}
return ret;
}

static List<double> UsingBlockCopy(double[,] array)
{
double[] tmp = new double[array.GetLength(0) * array.GetLength(1)];
Buffer.BlockCopy(array, 0, tmp, 0, tmp.Length * sizeof(double));
List<double> list = new List<double>(tmp);
return list;
}
}

结果(以毫秒为单位的时间);

LINQ: 253463
For loop: 9563
Block copy: 8697

编辑:将 for 循环更改为调用 array.GetLength()在每次迭代中,for 循环和 block 复制大约花费相同的时间。

关于c# - 将二维数组转换为列表(一维)的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5132397/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com