Ho un codice che esegue l'analisi dei file in base alle regole specificate. L'intera analisi si svolge in una monade che è una pila di ReaderT/STTrans/ErrorT.Quando si generalizza la monade, le prestazioni diminuiscono di quasi il 50%
type RunningRule s a = ReaderT (STRef s LocalVarMap) (STT s (ErrorT String Identity)) a
Perché sarebbe utile per eseguire alcuni IO nel codice (ad esempio, per interrogare i database esterni), ho pensato di generalizzare l'analisi, in modo che potesse funzionare sia in monade identità o IO base, a seconda la funzionalità che vorrei. La situazione è cambiata la firma di:
type RunningRule s m a = ReaderT (STRef s LocalVarMap) (STT s (ErrorT String m)) a
Dopo aver modificato le firme tipo appropriato (e con alcune estensioni per aggirare i tipi) ho corso di nuovo in monade Identità ed era ~ 50% più lento. Anche se sostanzialmente nulla è cambiato, è molto più lento. Questo comportamento normale? C'è un modo semplice per rendere questo più veloce? (ad esempio, combinando lo stack ErrorT e ReaderT (e possibilmente STT) in un trasformatore monad?)
Per aggiungere un campione di codice - è una cosa che sulla base di un input analizzato (fornito in linguaggio di tipo C) costruisce un parser. Il codice è simile al seguente:
compileRule :: forall m. (Monad m, Functor m) =>
-> [Data -> m (Either String Data)] -- For tying the knot
-> ParsedRule -- This is the rule we are compiling
-> Data -> m (Either String Data) -- The real parsing
compileRule compiled (ParsedRule name parsedlines) =
\input -> runRunningRule input $ do
sequence_ compiledlines
where
compiledlines = map compile parsedlines
compile (Expression expr) = compileEx expr >> return()
compile (Assignment var expr) =
...
compileEx (Function "check" expr) = do
value <- expr
case value of
True -> return()
False -> fail "Check failed"
where
code = compileEx expr
Hai compilato con ottimizzazioni e il profilo con criterio? Quali sono stati i passaggi di profilazione che hai preso per trovare questo rallentamento? – bheklilr
Compilato con ottimizzazioni, abilitato il profiling ed eseguito con + RTS -p, ha confrontato gli output - il risultato suggeriva principalmente nulla (a parte che probabilmente ha qualcosa a che fare con le monadi). Ho usato il "tempo" generale per controllare le prestazioni, i miei dati di test impiegavano 2 secondi con "Identità hardcoded" e 3 secondi quando permettevo di impostare la monade Identity come "parametro". – ondra
"e utilizzando alcune estensioni per aggirare i tipi" <- potrebbe indicare che qualcosa è cambiato di conseguenza. L'esempio di codice esteso in questione potrebbe aiutare a trovare prima una spiegazione. –