|
1 | 1 | using System;
|
2 | 2 | using System.Diagnostics.CodeAnalysis;
|
| 3 | +using System.Runtime.CompilerServices; |
3 | 4 | using System.Runtime.InteropServices;
|
| 5 | +using System.Threading.Tasks; |
4 | 6 | using NumSharp.Backends.Unmanaged;
|
5 | 7 | using NumSharp.Utilities;
|
6 | 8 |
|
@@ -1328,19 +1330,33 @@ public unsafe void CopyTo<T>(T[] array) where T : unmanaged
|
1328 | 1330 | }
|
1329 | 1331 | }
|
1330 | 1332 |
|
| 1333 | + [MethodImpl((MethodImplOptions)512)] |
1331 | 1334 | public unsafe T[] ToArray<T>() where T : unmanaged
|
1332 | 1335 | {
|
1333 | 1336 | if (typeof(T).GetTypeCode() != InternalArray.TypeCode)
|
1334 | 1337 | 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; |
1336 | 1340 | 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) |
1341 | 1343 | {
|
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 | + } |
1344 | 1360 |
|
1345 | 1361 | return ret;
|
1346 | 1362 | }
|
|
0 commit comments