Я работаю над проектом по моделированию физики, где производительность имеет решающее значение, и я думаю, что одним из узких мест является управление моей памятью. В настоящее время у меня есть буферные объекты, которые содержат фиксированное количество твердых тел, частиц и сил. Все физические объекты инициализируются в его буфере до начала симуляции. Когда требуется объект, выбирается первый неактивный, в противном случае - самый старый, а когда он больше не нужен, он перемещается в конец, поэтому все активные объекты упаковываются с фронта.
Вот структура данных, которую я использую.
public sealed class Buffer<TValue> : IEnumerable<BufferElement<TValue>> where TValue : new()
{
public Buffer(int capacity)
{
Count = 0;
Capacity = capacity;
Elements = new BufferElement<TValue>[capacity];
for (var index = 0; index < Elements.Length; index++)
{
Elements[index] = new BufferElement<TValue>();
}
}
public int Count { get; private set; }
public int Capacity { get; private set; }
private int ActiveCount { get; set; }
private BufferElement<TValue>[] Elements { get; }
public BufferElement<TValue> Activate()
{
if (Count == ActiveCount) Count = 0;
var bufferElement = Elements[Count++];
if (!bufferElement.Active)
{
bufferElement.Active = true;
ActiveCount++;
}
return bufferElement;
}
public void Deactivate(BufferElement element)
{
if (!element.Active) return;
element.Active = false;
var lhs = element.Index;
var rhs = --ActiveCount;
Elements[lhs] = Elements[rhs];
Elements[rhs] = element;
Elements[lhs].Index = lhs;
Elements[rhs].Index = rhs;
}
}
После прочтения того, как .NET Core обрабатывает массивы, могут возникнуть две проблемы. Во-первых, каждый раз, когда вы обращаетесь к элементу в массиве, он выполняет проверки безопасности, а во-вторых, GC может скопировать массив в новый адрес памяти.
Я хотел бы иметь все свои буферыкоторые содержат физические объекты, чтобы не выполнять предварительные проверки безопасности и быть фиксированными в непрерывной памяти, если это возможно. Я считаю, что это должно быть возможным, поскольку размер каждого буфера фиксирован, а размеры элементов (твердое тело, частица, сила) также фиксированы.
Кажется, что есть много способов управления памятьюв C #, и мне трудно понять, что было бы правильным для меня в этой ситуации.
Теперь вопрос сводится к трем частям:
- Можно ли это сделать?
- Если да, то какой метод управления памятью лучше всего?
- И как будет выглядеть правильная реализация?