В Haskell я создал вектор 1000000 IntMaps. Затем я использовал Gloss для рендеринга изображения таким образом, чтобы получить доступ к случайным intmaps из этого вектора.
То есть, я сохранил каждый из них в памяти. Сама функция рендеринга очень легкая, поэтому производительность должна быть хорошей.
Тем не менее, программа работала со скоростью 4 кадра в секунду. После профилирования я заметил, что 95% времени было потрачено на GC. Достаточно справедливо:
GC безумно сканирует мой вектор, хотя он никогда не меняется.
Есть ли способ рассказать GHC "это большое значение необходимо и не изменится - не пытайтесь собрать что-либо внутри него".
Изменить: нижеприведенной программы достаточно для репликации проблемы.
import qualified Data.IntMap as Map
import qualified Data.Vector as Vec
import Graphics.Gloss
import Graphics.Gloss.Interface.IO.Animate
import System.Random
main = do
let size = 10000000
let gen i = Map.fromList $ zip [mod i 10..0] [0..mod i 10]
let vec = Vec.fromList $ map gen [0..size]
let draw t = do
rnd <- randomIO :: IO Int
let empty = Map.null $ vec Vec.! mod rnd size
let rad = if empty then 10 else 50
return $ translate (20 * cos t) (20 * sin t) (circle rad)
animateIO (InWindow "hi" (256,256) (1,1)) white draw
Получает случайную карту на огромном векторе и рисует вращающийся круг, радиус которого зависит от того, пустое ли оно. Несмотря на то, что эта логика очень проста, программа здесь работает примерно на 1 FPS.