Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, vdimas, Вы писали:
V>>Напиши один раз "библиотечный" индексер и пользуйся.
S>Жду пример кода C4 фильтрации на основе "библиотечного" индексера.
Вдогонку, расширил пример на новомодный Span (который сам по себе уже абстрактный индексер).
Заодно из Span<T> легко получить unsafe, поэтому прогнал и его тоже.
Выходит, он удобен сугубо для получения slice-ов из произвольного участка managed или unmanaged памяти, разве что с последующим приведением к unsafe. ))
| Дополнительный код |
| unsafe readonly ref struct SpanIndexer2D<T>
{
public Span<T> array { get; }
public int dx { get; }
public int dy { get; }
public SpanIndexer2D(int dx, int dy)
{
this.dx = dx;
this.dy = dy;
array = new T[dx * dy];
}
public T this[int x, int y]
{
get => array[dx * y + x];
set => array[dx * y + x] = value;
}
}
unsafe readonly ref struct UnsafeIntArray2D
{
private readonly int* _array;
public int dx { get; }
public int dy { get; }
public UnsafeIntArray2D(int* array, int dx, int dy)
{
this.dx = dx;
this.dy = dy;
_array = array;
}
public int this[int x, int y]
{
get => _array[dx * y + x];
set => _array[dx * y + x] = value;
}
}
//...
static void SpanTest()
{
int dx = 1000, dy = 1000;
var array = new SpanIndexer2D<int>(dx, dy);
int sum = 0;
var rnd = new Random((int)DateTime.Now.TimeOfDay.Ticks);
for (int x = 0; x < array.dx; x++)
for (int y = 0; y < array.dy; y++)
array[x, y] = rnd.Next();
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
{
for (int x = 0; x < dx; x++)
for (int y = 0; y < dy; y++)
sum += array[x, y];
}
sw.Stop();
Console.WriteLine("Elapsed(ms)={0}", sw.Elapsed);
}
static unsafe void UnsafeTest()
{
int dx = 1000, dy = 1000;
var indexer = new SpanIndexer2D<int>(dx, dy);
fixed (int* intArray = indexer.array)
{
var array = new UnsafeIntArray2D(intArray, dx, dy);
int sum = 0;
var rnd = new Random((int)DateTime.Now.TimeOfDay.Ticks);
for (int x = 0; x < array.dx; x++)
for (int y = 0; y < array.dy; y++)
array[x, y] = rnd.Next();
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000; i++)
{
for (int x = 0; x < dx; x++)
for (int y = 0; y < dy; y++)
sum += array[x, y];
}
sw.Stop();
Console.WriteLine("Elapsed(ms)={0}", sw.Elapsed);
}
}
|
| |
Результаты:
Native 2D array: Elapsed(ms)=00:00:00.7712649
Emulated 2D array: Elapsed(ms)=00:00:00.6893393
Span 2D array: Elapsed(ms)=00:00:00.9882120
Unsafe 2D array: Elapsed(ms)=00:00:00.5858264
Upd. Перегнал релизный выхлоп в нейтив посредством NetNative, результаты те же.
Мде...