1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-26 17:13:35 +03:00
juvix/app/TreeEvaluator.hs
Jan Mas Rovira 3a4cbc742d
Replace polysemy by effectful (#2663)
The following benchmark compares juvix 0.6.0 with polysemy and a new
version (implemented in this pr) which replaces polysemy by effectful.

# Typecheck standard library without caching
```
hyperfine --warmup 2 --prepare 'juvix-polysemy clean' 'juvix-polysemy typecheck Stdlib/Prelude.juvix' 'juvix-effectful typecheck Stdlib/Prelude.juvix'
Benchmark 1: juvix-polysemy typecheck Stdlib/Prelude.juvix
  Time (mean ± σ):      3.924 s ±  0.143 s    [User: 3.787 s, System: 0.084 s]
  Range (min … max):    3.649 s …  4.142 s    10 runs

Benchmark 2: juvix-effectful typecheck Stdlib/Prelude.juvix
  Time (mean ± σ):      2.558 s ±  0.074 s    [User: 2.430 s, System: 0.084 s]
  Range (min … max):    2.403 s …  2.646 s    10 runs

Summary
  juvix-effectful typecheck Stdlib/Prelude.juvix ran
    1.53 ± 0.07 times faster than juvix-polysemy typecheck Stdlib/Prelude.juvix
```

# Typecheck standard library with caching
```
hyperfine --warmup 1 'juvix-effectful typecheck Stdlib/Prelude.juvix' 'juvix-polysemy typecheck Stdlib/Prelude.juvix' --min-runs 20
Benchmark 1: juvix-effectful typecheck Stdlib/Prelude.juvix
  Time (mean ± σ):      1.194 s ±  0.068 s    [User: 0.979 s, System: 0.211 s]
  Range (min … max):    1.113 s …  1.307 s    20 runs

Benchmark 2: juvix-polysemy typecheck Stdlib/Prelude.juvix
  Time (mean ± σ):      1.237 s ±  0.083 s    [User: 0.997 s, System: 0.231 s]
  Range (min … max):    1.061 s …  1.476 s    20 runs

Summary
  juvix-effectful typecheck Stdlib/Prelude.juvix ran
    1.04 ± 0.09 times faster than juvix-polysemy typecheck Stdlib/Prelude.juvix
```
2024-03-21 12:09:34 +00:00

63 lines
1.7 KiB
Haskell

module TreeEvaluator
( module TreeEvaluator,
module Commands.Dev.Tree.Eval.Options,
)
where
import App
import Commands.Dev.Tree.Eval.Options
import CommonOptions
import Juvix.Compiler.Tree.Data.InfoTable qualified as Tree
import Juvix.Compiler.Tree.Error qualified as Tree
import Juvix.Compiler.Tree.Evaluator qualified as Tree
import Juvix.Compiler.Tree.EvaluatorEff qualified as Eff
import Juvix.Compiler.Tree.Language.Value qualified as Tree
import Juvix.Compiler.Tree.Pretty qualified as Tree
evalTree :: forall r. (Members '[EmbedIO, App] r) => Evaluator -> Tree.InfoTable -> Sem r ()
evalTree ev tab =
case tab ^. Tree.infoMainFunction of
Just sym -> do
r <- doEval ev tab (Tree.lookupFunInfo tab sym)
case r of
Left err ->
exitJuvixError (JuvixError err)
Right Tree.ValVoid ->
return ()
Right val -> do
renderStdOut (Tree.ppOutDefault tab val)
putStrLn ""
Nothing ->
exitMsg (ExitFailure 1) "no 'main' function"
doEvalDefault ::
(MonadIO m) =>
Tree.InfoTable ->
Tree.FunctionInfo ->
m (Either Tree.TreeError Tree.Value)
doEvalDefault = doEval defaultEvaluator
doEval ::
(MonadIO m) =>
Evaluator ->
Tree.InfoTable ->
Tree.FunctionInfo ->
m (Either Tree.TreeError Tree.Value)
doEval = \case
EvalEffectful -> doEvalEff
EvalRaw -> doEvalRaw
doEvalRaw ::
(MonadIO m) =>
Tree.InfoTable ->
Tree.FunctionInfo ->
m (Either Tree.TreeError Tree.Value)
doEvalRaw tab' = liftIO . Tree.catchEvalErrorIO . liftIO . Tree.hEvalIO stdin stdout tab'
doEvalEff ::
(MonadIO m) =>
Tree.InfoTable ->
Tree.FunctionInfo ->
m (Either Tree.TreeError Tree.Value)
doEvalEff tab' funInfo = Eff.hEvalIOEither stdin stdout tab' funInfo