2013-04-07 2 views
1

Возможно ли ускорить (или в случае моей функции, удалить) проверку равенства в Haskell? У меня есть функция, которая суммирует все взаимодействие агента, где взаимодействия между двумя агентами. Чтобы суммировать взаимодействие, сначала нужно проверить, равен ли агент первому или второму агенту во взаимодействии, а затем суммирует его. Проверка на равенство занимает почти половину времени работы моих программ.Ускорение проверки равенства в Haskell

sumAgent :: [Interaction] -> Agent -> Int 
sumAgent xs agent = foldr (\x acc -> acc + sumInteraction agent x) 0 xs 

-- Use this in a map call of sumAgent to return the sums of a specific agent 
sumInteraction :: Agent -> Interaction -> Int 
sumInteraction agent (Interaction a1 a2 xs) 
    | (==) agent a1 = sum $ map fst scores 
    | (==) agent a2 = sum $ map snd scores 
    | otherwise = 0 
    where scores = map score xs 

Можно ли удалить проверку равенства, или ускорить его, используя функцию с, или проверять равенство только часть агента? Реализация Eq:

data Agent = Agent { 
       function::[(Bool,Bool)] -> Bool, 
       name::String, 
       position::(Int,Int), 
       dna::DNA 
       } 
instance Eq Agent where 
     (==) a1 a2 = position a1 == position a2 
+2

Вы предоставили недостаточно информации, чтобы ответить на ваши вопросы. 'position' может быть дорогостоящим вычислением, а также записывать геттер. Также рассмотрим рефакторинг алгоритмов и структур данных. Вероятно, будет дешевле поддерживать списки инцидентов на каждом агенте, чем фильтровать общий список взаимодействий каждый раз, когда вам нужно агрегировать взаимодействия агента. – leventov

+1

Кроме того, убедитесь, что вы компилируете программу с флагом '-O2', если хотите оценить производительность. – leventov

+1

Кстати, вы всегда можете разместить операторы infix между аргументами: '| agent == a1 = ... ',' a1 == a2 = pos ... ' – leventov

ответ

2

Как вы знаете, что равенство занимает половину времени? Я предполагаю, что вы, скорее всего, чтобы получить выигрыш в производительности при использовании жесткого и распакованный пара:

data Pair = P {-# UNPACK #-} !Int {-# UNPACK #-} !Int 
data Agent = Agent { 
      function::[(Bool,Bool)] -> Bool, 
      name::String, 
      position:: {-# UNPACK #-} !Pair Int Int, 
      dna::DNA 
      } 

Таким образом, вы избежите дополнительных окольные и, вероятно, получить лучшее поведение кэша.

Смежные вопросы