Я работаю над оптимизацией программы моделирования физики, используя Red Gate Performance Profiler. Одна часть кода, касающаяся обнаружения столкновений, имела около 52 из следующих небольших проверок, касающихся ячеек в 26 направлениях в трех измерениях, в двух случаях.
CollisionPrimitiveList cell = innerGrid[cellIndex + 1];
if (cell.Count > 0)
contactsMade += collideWithCell(obj, cell, data, ref attemptedContacts);
cell = innerGrid[cellIndex + grid.XExtent];
if (cell.Count > 0)
contactsMade += collideWithCell(obj, cell, data, ref attemptedContacts);
cell = innerGrid[cellIndex + grid.XzLayerSize];
if (cell.Count > 0)
contactsMade += collideWithCell(obj, cell, data, ref attemptedContacts);
Как чрезвычайно сложный цикл программы, все это должно было быть одним и тем же методом, но я обнаружил, что внезапно после того, как я расширил область от двух измерений до трех измерений (увеличение числа до 52 проверок от 16), вдруг cell.Count уже не был привязан, хотя это простой геттер.
public int Count { get { return count; } }
Это вызвало огромный удар по производительности, и мне потребовалось немало времени, чтобы обнаружить, что, когда cell.Count появился в методе 28 раз или меньше, он был вложен каждый раз, но как только cell.Count появился в методе 29 раз или более, он не был установлен в одно время (хотя подавляющее большинство звонков было из наихудшего сценария части кода, которые редко выполнялись.)
Итак, вернемся к моему вопросу, есть ли у кого-нибудь идеи обойти этот предел? Я думаю, что простое решение состоит в том, чтобы сделать поле счетчика внутренним, а не частным, но я бы хотел получить лучшее решение, чем это, или, по крайней мере, просто лучше понять ситуацию. Я бы хотел, чтобы подобное было упомянуто на странице "Высокопроизводительные управляемые приложения Microsoft Writing" на http://msdn.microsoft.com/en-us/library/ms973858.aspx, но, к сожалению, это не так (возможно, потому что от того, насколько произвольным считается ограничение на количество 28?)
Я использую .NET 4.0.
EDIT: Похоже, я неверно истолковал свое небольшое тестирование. Я обнаружил, что отказ встроенных был вызван не самими методами, а называемыми примерно 28+ раз, но потому, что метод, которым они должны быть встроены, является "слишком длинным" по некоторому стандарту. Это все еще меня смущает, потому что я не вижу, как простой геттер может быть рационально не привязан (и производительность значительно лучше с ними, так как мой профилировщик явно показывает мне), но, по-видимому, компилятор CLI JIT отказывается встраивать что-либо только потому, что метод уже велик (игра с небольшими вариациями показала мне, что этот предел - это размер кода (от idasm) 1500, выше которого не выполняется ни одна вставка, даже в случае моих геттеров, которые, как показали некоторые тесты, не добавили дополнительного кода накладные расходы должны быть встроены).
Спасибо.