Skip to content

Commit 088103a

Browse files
committed
NDArray.ToArray(): revamped and perf-optted
1 parent 8c97561 commit 088103a

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

src/NumSharp.Core/Backends/Unmanaged/UnmanagedStorage.cs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Diagnostics.CodeAnalysis;
3+
using System.Runtime.CompilerServices;
34
using System.Runtime.InteropServices;
5+
using System.Threading.Tasks;
46
using NumSharp.Backends.Unmanaged;
57
using NumSharp.Utilities;
68

@@ -1328,19 +1330,33 @@ public unsafe void CopyTo<T>(T[] array) where T : unmanaged
13281330
}
13291331
}
13301332

1333+
[MethodImpl((MethodImplOptions)512)]
13311334
public unsafe T[] ToArray<T>() where T : unmanaged
13321335
{
13331336
if (typeof(T).GetTypeCode() != InternalArray.TypeCode)
13341337
throw new ArrayTypeMismatchException($"The given type argument '{typeof(T).Name}' doesn't match the type of the internal data '{InternalArray.TypeCode}'");
1335-
var addr = (T*)Address;
1338+
1339+
var src = (T*)Address;
13361340
var ret = new T[Shape.Size];
1337-
var incr = new NDCoordinatesIncrementor(Shape.dimensions);
1338-
int[] current = incr.Index;
1339-
int i = 0;
1340-
do
1341+
1342+
if (Shape.IsContiguous)
13411343
{
1342-
ret[i++] = (*(addr + Shape.GetOffset(current)));
1343-
} while (incr.Next() != null);
1344+
fixed (T* dst = ret)
1345+
{
1346+
var len = sizeof(T) * ret.Length;
1347+
Buffer.MemoryCopy(src, dst, len, len);
1348+
}
1349+
}
1350+
else
1351+
{
1352+
var incr = new NDCoordinatesIncrementor(Shape.dimensions);
1353+
int[] current = incr.Index;
1354+
Func<int[], int> getOffset = Shape.GetOffset;
1355+
int i = 0;
1356+
1357+
do ret[i++] = src[getOffset(current)];
1358+
while (incr.Next() != null);
1359+
}
13441360

13451361
return ret;
13461362
}

0 commit comments

Comments
 (0)