我得到了以下代码:
Boo[,,] boos = new Boo[8, 8, 8];
Boo GetMe(int i, int j, int k)
{
return boos[i, j, k];
}
上面的代码效率很低,所以我将其转换为一维数组:
Boo[] boosone;
Boo[,,] boos = new Boo[8, 8, 8];
Boo GetMe(int i, int j, int k)
{
if (boosone == null)
{
boosone = new Boo[8 * 8 * 8];
int num = 0;
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
for (int z = 0; z < 8; z++)
{
boosone[num] = boos[x, y, z];
num++;
}
}
}
}
return boosone[?];
}
如何从一维数组boosone
中获取Boo
(与多维数组j
k
l
中的位置相同)
发布于 2019-03-04 19:15:50
为什么你不看看能提供更好性能的锯齿数组呢?我做了一个测试(在RELEASE configuration下),结果显示包装器比d3数组快两倍,但是d3数组快3倍。
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
namespace ArrayWrapper
{
class ArrayPerformanceTest
{
int xSize = 2;
int ySize = 3;
int zSize = 4;
int count = 100000000;
int delay = 500;
static void Main(string[] args)
{
new ArrayPerformanceTest().Run();
}
private void Run()
{
var d3Array = CreateD3Array();
var wrapped = GetD1Adapter(d3Array);
var jagged = GetJaggedArray(d3Array);
Thread.Sleep(delay);
TestD3Array(d3Array);
Thread.Sleep(delay);
TestWrappedArray(wrapped);
Thread.Sleep(delay);
TestJaggeddArray(jagged);
Thread.Sleep(delay);
}
private int[,,] CreateD3Array()
{
var rectangular = new int[xSize, ySize, zSize];
int i = 7;
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
rectangular[x, y, z] = ++i;
return rectangular;
}
private int[] GetD1Adapter(int[,,] d3Array)
{
return d3Array.Cast<int>().ToArray();
}
private int[][][] GetJaggedArray(int[,,] d3Array)
{
var xSize = d3Array.GetUpperBound(0) + 1;
var ySize = d3Array.GetUpperBound(1) + 1;
var zSize = d3Array.GetUpperBound(2) + 1;
var jagged = new int[xSize].Select(j => new int[ySize].Select(k => new int[zSize].ToArray()).ToArray()).ToArray();
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
jagged[x][y][z] = d3Array[x, y, z];
return jagged;
}
private void TestD3Array(int[,,] d3Array)
{
int i;
var sw = new Stopwatch();
sw.Start();
for (var c = 0; c < count; c++)
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
i = d3Array[x, y, z];
sw.Stop();
Console.WriteLine($"{nameof(d3Array),7} {sw.ElapsedTicks,10}");
}
private void TestWrappedArray(int[] wrapped)
{
int i;
var sw = new Stopwatch();
sw.Start();
for (var c = 0; c < count; c++)
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
i = wrapped[x * ySize * zSize + y * zSize + z];
sw.Stop();
Console.WriteLine($"{nameof(wrapped),7} {sw.ElapsedTicks,10}");
}
private void TestJaggeddArray(int[][][] jagged)
{
int i;
var sw = new Stopwatch();
sw.Start();
for (var c = 0; c < count; c++)
for (var x = 0; x < xSize; x++)
for (var y = 0; y < ySize; y++)
for (var z = 0; z < zSize; z++)
i = jagged[x][y][z];
sw.Stop();
Console.WriteLine($"{nameof(jagged),7} {sw.ElapsedTicks,10}");
}
}
}
输出:
d3Array 15541709
wrapped 8213316
jagged 5322008
我还分析了CPU的使用情况。
这三种方法的速率都是相同的。
发布于 2019-03-04 04:56:30
我真的不确定为什么你说第一个3D数组效率不高(我的意思是,你有没有注意到在使用它时速度特别慢?),但你可以通过一些简单的偏移计算来做到这一点。
首先,如果您的目标是最新的C#版本,您可以仅用两行代码替换整个复制功能,然后您的代码将如下所示:
using System;
using System.Runtime.InteropServices;
Boo[] boosone;
Boo[,,] boos = new Boo[8, 8, 8];
Boo GetMe(int i, int j, int k)
{
if (boosone == null)
{
boosone = new Boo[boos.Length];
MemoryMarshal.CreateSpan(ref boos[0, 0, 0], boosone.Length).CopyTo(boosone);
}
return boosone[boos.GetLength(1) * boos.GetLength(2) * i + boos.GetLength(2) * j + k];
}
如果你出于某种原因不想使用MemoryMarshal
类,你也可以使用LINQ来展平你的3D数组,尽管这种方法的效率要低得多:
boosone = boos.Cast<Boo>().ToArray();
发布于 2019-03-04 04:59:21
int index = (8 * 8 * i) + (8 * j) + k;
return boosone[index];
https://stackoverflow.com/questions/54973574
复制相似问题