Вычисление точек на расстоянии для каждой точки составляет O (n ^ 2), поэтому не так уж странно, что производительность падает, если количество частиц велико. Но это довольно легко можно улучшить. Есть несколько вариантов структур поиска, которые можно использовать:
- 3D сетка. Это должно быть просто реализовать, просто создайте трехмерный массив списков. Выберите подходящий размер ящика, чтобы у вас было фиксированное количество ячеек для перебора. Основным недостатком этого является использование памяти, оно будет более значительным, если в вашей симуляции есть большие пустоты без частиц.
- Редкое октодерево. Основным преимуществом перед сеткой будет лучшее использование памяти, если точки расположены неравномерно. Также было бы лучше масштабироваться, если вам нужно искать произвольное расстояние. Обратной стороной будет более сложная реализация.
- KdTree. Это довольно хорошая структура данных, поскольку она использует довольно мало памяти, может быть реализована с непрерывной памятью и хорошо масштабируется. Одним из недостатков является то, что трудно справиться со сменой позиций. Реализация также более сложна, чем сетка.
Для сетки или Octree можно было бы перемещать точки между ячейками. Для kd-дерева, вероятно, было бы лучше перестроить дерево. Любой из вариантов должен сократить время поиска с O (N ^ 2) до O (n log n).
Учитывая контекст вашего вопроса, я бы рекомендовал начать с простой 3D-сетки. Если этого недостаточно, я бы подумал об использовании дерева kd. Я бы избегал комбинирования структур данных, если для этого нет какой-либо конкретной c причины. Octrees и kdtrees должны достаточно хорошо масштабироваться.
Я бы рекомендовал попробовать некоторые инструменты профилирования , чтобы проверить, что на самом деле требует времени. Я также рекомендовал бы настроить некоторую контролируемую среду для запуска алгоритма на известном наборе данных и измерения времени. Бенчмарк. Net - золотой стандарт, но простой секундомер должен быть достаточно хорош при измерении больших изменений.
Также должна быть некоторая возможность для микрооптимизации. Избегайте создания списков в жестком l oop, при необходимости создайте список, который будет использоваться повторно. Избегайте повторных операций. Избегайте дорогостоящих операций. Предпочитайте массивы и списки другим коллекциям, поскольку среда выполнения имеет для них особую оптимизацию. Предпочитайте for
вместо foreach
, поскольку первое может избежать создания объекта итератора.