У меня есть нерекурсивная функция для вычисления самой длинной общей подпоследовательности, которая, кажется, хорошо работает (ghc 7.6.1
, скомпилирована с флагами -O2 -fllvm
), если я измеряю ее с помощью Criterion
в том же модуле. С другой стороны, если я преобразую функцию в модуль, экспортируйте именно эту функцию (как рекомендовано здесь), а затем снова измерьте с помощью Criterion, я получаю ~ 2x спад (который уходит, если я переведу критерий теста обратно в модуль, где определена функция). Я попытался отметить функцию с помощью INLINE
pragma, которая не имела никакого значения для измерения производительности кросс-модуля.
Мне кажется, что GHC может проводить анализ строгости, который хорошо работает, когда функция и основная функция (из которой доступна эта функция) находятся в одном модуле, но не тогда, когда они разделены. Я бы очень хотел, чтобы указатели на модульность функции, чтобы она хорошо работала при вызове из других модулей. Этот код слишком большой, чтобы вставить здесь - вы можете увидеть его здесь, если хотите попробовать. Небольшой пример того, что я пытаюсь сделать, ниже (с фрагментами кода):
-- Function to find longest common subsequence given unboxed vectors a and b
-- It returns indices of LCS in a and b
lcs :: (U.Unbox a, Eq a) => Vector a -> Vector a -> (Vector Int,Vector Int)
lcs a b | (U.length a > U.length b) = lcsh b a True
| otherwise = lcsh a b False
-- This section below measures performance of lcs function - if I move it to
-- a different module, performance degrades ~2x - mean goes from ~1.25us to ~2.4us
-- on my test machine
{--
config :: Config
config = defaultConfig { cfgSamples = ljust 100 }
a = U.fromList ['a'..'j'] :: Vector Char
b = U.fromList ['a'..'k'] :: Vector Char
suite :: [Benchmark]
suite = [
bench "lcs 10" $ whnf (lcs a) b
]
main :: IO()
main = defaultMainWith config (return ()) suite
--}