Добър начин да избегнете споделянето?

Да предположим, че някой би превел този прост код на Python на Haskell:

def important_astrological_calculation(digits):
  # Get the first 1000000 digits of Pi!
  lucky_numbers = calculate_first_digits_of_pi(1000000)
  return digits in lucky_numbers

Haskell версия:

importantAstrologicalCalculation digits =
  isInfixOf digits luckyNumbers
  where
    luckyNumbers = calculateFirstDigitsOfPi 1000000

След като работи с версията на Haskell, програмистът с изненада открива, че неговата версия на Haskell "изпуска" памет - след първото извикване на неговата функция, luckyNumbers никога не се освобождава. Това е обезпокоително, тъй като програмата включва още няколко подобни функции и паметта, консумирана от всички тях, е значителна.

Има ли лесен и елегантен начин програмата да "забрави" luckyNumbers?


person yairchu    schedule 07.07.2011    source източник
comment
Не е елегантно, но какво ще стане, ако добавите {-# NOINLINE importantAstrologicalCalculation #-}?   -  person John L    schedule 07.07.2011
comment
Наскоро имаше въпрос, който питаше очевидно същото, но използваше по-напреднала терминология. Може да искате да го разгледате: stackoverflow.com/questions/6090932/   -  person Rotsor    schedule 07.07.2011


Отговори (1)


В този случай вашият списък с pidigits е константа (или "константна приложна форма") и GHC вероятно ще го изведе, ще го изчисли веднъж и ще сподели между използваните. Ако няма препратки към CAF, той ще бъде събран боклук.

Сега, като цяло, ако искате нещо да бъде преизчислено, превърнете го във функция (напр. като добавите фиктивен параметър ()). Примери в свързания въпрос относно CAF: Как да направите CAF не е CAF в Haskell?

person Don Stewart    schedule 07.07.2011
comment
Изнасянето му променя ли нещо? stackoverflow.com/questions/6208006 създава подобна ситуация, без нищо да е константа.. - person yairchu; 09.07.2011