Агентное моделирование: проблема производительности: Python vs NetLogo & Repast
-
29-10-2019 - |
Вопрос
Я копирую небольшой фрагмент имитационной модели агента Sugarscape в Python 3. Я обнаружил, что производительность моего кода примерно в 3 раза ниже, чем у NetLogo. Вероятно, это проблема с моим кодом, или это может быть внутреннее ограничение Python?
Очевидно, что это всего лишь фрагмент кода, но именно на него Python тратит две трети времени выполнения. Надеюсь, если бы я написал что-то действительно неэффективное, это могло бы проявиться в этом фрагменте:
общийПримерно эквивалентный код в NetLogo (этот фрагмент делает немного больше, чем функция Python выше) :
общийНа моем компьютере код Python выполняет 1000 шагов за 15,5 секунды; на том же ноутбуке имитация NetLogo, выполняемая на Java в браузере, выполняет 1000 шагов менее чем за 6 секунд.
РЕДАКТИРОВАТЬ: только что проверил Repast, используя реализацию Java. И это примерно то же самое, что и NetLogo - 5,4 секунды. Недавние сравнения между Java и Python не указывают на преимущества Java , значит, виноват только мой код?
РЕДАКТИРОВАТЬ: я понимаю, что MASON должен быть даже быстрее, чем Ешьте, и все же в конце концов он все равно запускает Java.
Решение
Это, вероятно, не даст значительного ускорения, но вы должны знать, что локальные переменные в Python намного быстрее, чем доступ к глобальным переменным или атрибутам.Итак, вы можете попробовать присвоить локальным переменным некоторые значения, которые используются во внутреннем цикле, например:
общий Вызов функций в Python также имеет относительно высокие накладные расходы (по сравнению с Java), поэтому вы можете попытаться продолжить оптимизацию, заменив функцию occupied
прямым поиском по словарю.
Вам также следует взглянуть на psyco .Это своевременный компилятор для Python, который в некоторых случаях может значительно улучшить скорость.Однако он еще не поддерживает Python 3.x, поэтому вам придется использовать более старую версию Python.
Другие советы
Я собираюсь предположить, что способ реализации кода neighborhood
в NetLogo отличается от двойного цикла, который у вас есть.В частности, я думаю, что они предварительно вычисляют вектор соседства, например
(вам понадобится другой для vision= 1,2, ...), а затем используйте только один цикл для n
вместо вложенного цикла, как вы делаете.Это устраняет необходимость в умножении.
Я не думаю, что это даст вам 3-кратное ускорение.
Это старый вопрос, но я предлагаю вам изучить использование NumPy для ускорения ваших операций.В местах, где вы используете словари и списки, которые логически организованы (1-, 2-, 3- или N-мерная сетка), однородный объект данных (все целые числа или все числа с плавающей запятой и т. Д.) Будут иметь меньше накладных расходов при представлении и доступе как Numpyмассивы.
Вот сравнительно актуальное сравнение NetLogo и одной из версий Repast.Я бы не стал предполагать, что трапеза быстрее.NetLogo, похоже, содержит несколько очень умных алгоритмов, которые могут компенсировать любые затраты. http://condor.depaul.edu/slytinen/abm/Lytinen-Railsback-EMCSR_2012-02-17.pdf