是否可以将新的System.Memory Span struct与二维数据数组一起使用?
double[,] testMulti =
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 9.5f, 10, 11 },
{ 12, 13, 14.3f, 15 }
};
double[] testArray = { 1, 2, 3, 4 };
string testString = "Hellow world";
testMulti.AsSpan(); // Compile error
testArray.AsSpan();
testString.AsSpan();
虽然testArray和testString具有AsSpan扩展名,但testMulti不存在此类扩展名。
Span的设计是否仅限于处理一维数据数组?
我找不到使用Span处理testMulti数组的明显方法。
答案 0 :(得分:3)
您可以使用不受管理的内存创建一个type text
。这样一来,您就可以随意切片和切丁。
Span
完整演示
unsafe
{
Span<T> something = new Span<T>(pointerToarray, someLength);
}
输出
unsafe public static void Main(string[] args)
{
double[,] doubles = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 9.5f, 10, 11 },
{ 12, 13, 14.3f, 15 }
};
var length = doubles.GetLength(0) * doubles.GetLength(1) * sizeof(double);
fixed (double* p = doubles)
{
var span = new Span<double>(p, length);
var slice = span.Slice(6, 5);
foreach (var item in slice)
Console.WriteLine(item);
}
}
其他选择是将其重新分配给一维数组,应对惩罚,并请勿通过
7
8
9
9.5
10
BlockCopy
并使用memcpy
和指针unsafe
例如Cast<T>
对于大型数组,前2个将表现更好。
答案 1 :(得分:1)
所有跨度都是一维的,因为内存是一维的。
您当然可以将所有形式的结构映射到一维内存中,但是Span类不会为您完成此操作。但是您可以自己轻松地写一些东西,例如:
Slice()
棘手的部分是实现void OnGUI(){
GUI.Label(new Rect(0,0,0,0),userUpdate);
}
,因为对于二维结构,语义有点模棱两可。您可能只能按一个维度对这种结构进行切片,因为按另一个维度对这种结构进行切片会导致内存不连续。
答案 2 :(得分:1)
正如 John Wu 已经提到的,跨度是一维的。 您当然可以自己实现 2D 跨度,但 Microsoft 已经为我们做到了。
查看文档 here。
您可以找到寻址 nuget 包 here。
该包还提供了一个 Memory2D。
var arr = new int[,] { {1,2,3},{2,2,3},{3,2,3} };
var spn = arr.AsSapn2D();
// Now use it similar to a normal span
// The access is of course a bit different since we are using a 2D data structure.
Console.WriteLine(spn[0..2,..]);
答案 3 :(得分:0)
作为@saruman,我认为这是不可能的。
例如,您首先需要使用Fast way to convert a two dimensional array to a List ( one dimensional )或Convert 2 dimensional array中显示的技术来获得一个新的单维数组。
答案 4 :(得分:0)
也许使用锯齿数组而不是多维数组会获得更大的成功。
double[][] testMulti =
{
new double[] { 1, 2, 3, 4 },
new double[] { 5, 6, 7, 8 },
new double[] { 9, 9.5f, 10, 11 },
new double[] { 12, 13, 14.3f, 15 }
};
Span<double[]> span = testMulti.AsSpan(2, 1);
Span<double> slice = span[0].AsSpan(1, 2);
foreach (double d in slice)
Console.WriteLine(d);
slice[0] = 10.5f;
Console.Write(string.Join(", ", testMulti[2]));
Console.ReadLine();
输出
9.5
10
9, 10.5, 10, 11