Следует проверить изменения перед написанием IORef?

Есть код, который читает IORef и на основе некоторых условий и вычислений создает новое значение. Теперь он записывает новое значение в этот IORef. Но есть шанс, что это не изменилось вообще. Новое значение может быть идентично старому.

Каковы соображения относительно того, стоит ли проверять, отличается ли значение перед записью IORef, или просто записать IORef независимо от этого?

Проверяет ли writeIORef, изменяется ли значение перед установкой?

Проверив сначала, не могли бы вы избежать записи и сэкономить немного на производительности?

1 ответ

Решение

Проверяет ли writeIORef, изменяется ли значение перед установкой?

Нет. writeIORef обертывания writeSTRef, который определяется как

-- |Write a new value into an 'STRef'
writeSTRef :: STRef s a -> a -> ST s ()
writeSTRef (STRef var#) val = ST $ \s1# ->
    case writeMutVar# var# val s1#      of { s2# ->
    (# s2#, () #) }

Проверив сначала, не могли бы вы избежать записи и сэкономить немного на производительности?

Каковы соображения относительно того, стоит ли проверять, отличается ли значение перед записью IORef, или просто записать IORef независимо от этого?

Это действительно зависит от рассматриваемого алгоритма. Что вы пытаетесь оптимизировать? Какова частота чтения / записи? какие данные вы храните? как это упаковано? Какова стоимость сравнения равенства для рассматриваемых данных?

Существует целый ряд факторов, которые необходимо учитывать при определении того, хотите ли вы деструктивно обновлять ячейки на месте: некоторые зависят от алгоритма, некоторые зависят от местоположения кэша, другие зависят от структуры и формы кода, генерируемого GHC. Таким образом, чрезвычайно сложно ответить на ваш вопрос.

Цитата от Дональда Кнута:

Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всех зол

Если вы не находитесь на той стадии, когда вы пытаетесь извлечь хоть какой-то минимум производительности из какой-то хорошо понятой реализации, вам, вероятно, лучше выбрать путь, который

  • проще всего реализовать
  • проще всего рассуждать о

и ладить с этим. Если вы находитесь на этапе, когда вы хотите настроить свою программу, я бы посоветовал научиться читать сгенерированный человеком вывод GHC (Core), поскольку тогда вы сможете принимать решения такого рода (на очень детальный уровень) для каждой программы.

Другие вопросы по тегам