У меня есть несколько операций с хрустом числа, которые учитывают значительную часть времени процессора. Одним из примеров таких операций является эта функция:
import Data.Number.Erf
import Math.Gamma
import Math.GaussianQuadratureIntegration as GQI
-- Kummer's' "1F1" a.k.a M(a,b,z) Confluent Hypergeometric function
-- Approximation by the Gaussian Quadrature method from 128 up to 1024 points of resolution
kummer :: Double -> Double -> Double -> Double -> Double
kummer a b z err = gammaFactor * integralPart
where
gammaFactor = (gamma b) / (gamma a * gamma (b-a))
integralPart = (integrator err) fun 0 1
fun = (\t -> (e ** (z * t)) * (1-t) ** (b-a-1) * t ** (a-1))
e = exp 1
integrator err
| err > 0.1 = GQI.nIntegrate128
| err > 0.01 = GQI.nIntegrate256
| err > 0.001 = GQI.nIntegrate512
| otherwise = GQI.nIntegrate1024
SO, мне было интересно, есть ли какие-то правила, чтобы следить за тем, когда функция должна быть INLINE для повышения производительности. REPA Авторы предлагают:
Добавьте прагмы INLINE ко всем функциям листа в вашем коде, особенно которые вычисляют числовые результаты. Необязательные ленивые вызовы функций могут стоить до 50 циклов каждый, в то время как каждый числовой оператор стоит только один (или менее). Встраивание функций листа также гарантирует, что они специализированы на соответствующих числовых типах.
Являются ли эти указания применимыми к остальным численным вычислениям или только к вычислениям в массиве? или есть более общее руководство, чтобы решить, когда функция должна быть встроенной?
Обратите внимание, что это сообщение: Есть ли причина не использовать прагму INLINABLE для функции? не затрагивает непосредственно вопрос о том, если подсказки, предоставленные программистом действительно помогите компилятору оптимизировать код.