Я пишу игровой ай (aichallenge.org - Ants), который требует много обновлений и ссылается на структуры данных. Я пробовал как массивы, так и карты, но основная проблема заключается в том, что каждое обновление создает новое значение, что делает его медленным. Игра загружает вас, если вы потратите более одной секунды, чтобы сделать свой ход, поэтому приложение считается "жестким в реальном времени". Возможно ли иметь производительность изменчивых структур данных в Haskell, или я должен изучить Python или переписать мой код в OCaml?
Я полностью переписал "стартовый пакет" муравьев. Изменено с массивов на Карты, потому что мои тесты показали, что Карты обновляются намного быстрее.
Я запустил версию Maps с профилированием, которая показала, что около 20% времени выполняется только обновлениями карт.
Вот простая демонстрация того, насколько медленны обновления Array.
slow_array =
let arr = listArray (0,9999) (repeat 0)
upd i ar = ar // [(i,i)]
in foldr upd arr [0..9999]
Теперь, оценивая slow_array! 9999 занимает почти 10 секунд! Хотя было бы быстрее применять все обновления сразу, пример моделирует реальную проблему, когда массив должен обновляться каждый ход, и предпочтительно каждый раз, когда вы выбираете ход при планировании следующего хода.
Благодаря nponeccop и Tener для ссылки на векторные модули. Следующий код эквивалентен моему первоначальному примеру, но работает за 0,06 секунды вместо 10.
import qualified Data.Vector.Unboxed.Mutable as V
fast_vector :: IO (V.IOVector Int)
fast_vector = do
vec <- V.new 10000
V.set vec 0
mapM_ (\i -> V.write vec i i) [0..9999]
return vec
fv_read :: IO Int
fv_read = do
v <- fast_vector
V.read v 9999
Теперь, чтобы включить это в мой код Ants...