Я пишу игровой ai (aichallenge.org - Ants), который требует большого обновления и обращения к данным: конструкции. Я пробовал как массивы, так и карты, но основная проблема, похоже, заключается в том, что каждое обновление создает новое значение, что замедляет его работу. Игра загружает вас, если на ход у вас уходит больше одной секунды, поэтому приложение считается «работающим в режиме жесткого реального времени». Возможно ли получить производительность изменяемых структур данных в Haskell, или мне следует изучить Python или переписать свой код в OCaml?
Я полностью переписал «стартовый пакет» Ants. Изменен с массивов на карты, потому что мои тесты показали, что карты обновляются намного быстрее.
Я запустил версию Карт с включенным профилированием, которая показала, что около 20% времени уходит только на обновления карты.
Вот простая демонстрация того, насколько медленными являются обновления массива.
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 ...