-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize
letFunctionDefs
in Juvix.Compiler.Internal.Data.InfoTable
(
#2867) * Closes #2394 * Removes the use of Uniplate in `letFunctionDefs` altogether, in favour of handwritten traversal accumulating let definitions (implemented via the new `HasLetDefs` typeclass). Benchmark results ------------------ Using Uniplate: ``` heliax@imac bench % hyperfine --prepare 'juvix clean --global' -w 1 'juvix typecheck bench.juvix -N 1' Benchmark 1: juvix typecheck bench.juvix -N 1 Time (mean ± σ): 1.399 s ± 0.023 s [User: 1.346 s, System: 0.041 s] Range (min … max): 1.374 s … 1.452 s 10 runs ``` Using `HasLetDefs`: ``` heliax@imac bench % hyperfine --prepare 'juvix clean --global' -w 1 'juvix typecheck bench.juvix -N 1' Benchmark 1: juvix typecheck bench.juvix -N 1 Time (mean ± σ): 1.098 s ± 0.015 s [User: 1.047 s, System: 0.040 s] Range (min … max): 1.074 s … 1.120 s 10 runs ``` So it's roughly 1.1s vs. 1.4s, faster by 0.2s. About 14% improvement. The benchmark file just imports the standard library: ``` module bench; import Stdlib.Prelude open; main : Nat := 0; ``` Both `juvix` binaries were compiled with optimizations, using `just install`.
- Loading branch information
Showing
3 changed files
with
106 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
module Juvix.Compiler.Internal.Extra.HasLetDefs where | ||
|
||
import Juvix.Compiler.Internal.Language | ||
import Juvix.Prelude | ||
|
||
class HasLetDefs a where | ||
letDefs' :: [Let] -> a -> [Let] | ||
letDefs :: a -> [Let] | ||
letDefs = letDefs' [] | ||
|
||
instance (HasLetDefs a, Foldable f) => HasLetDefs (f a) where | ||
letDefs' = foldl' letDefs' | ||
|
||
instance HasLetDefs Expression where | ||
letDefs' acc = \case | ||
ExpressionIden {} -> acc | ||
ExpressionApplication x -> letDefs' acc x | ||
ExpressionFunction x -> letDefs' acc x | ||
ExpressionLiteral {} -> acc | ||
ExpressionHole {} -> acc | ||
ExpressionInstanceHole {} -> acc | ||
ExpressionLet x -> letDefs' acc x | ||
ExpressionUniverse {} -> acc | ||
ExpressionSimpleLambda x -> letDefs' acc x | ||
ExpressionLambda x -> letDefs' acc x | ||
ExpressionCase x -> letDefs' acc x | ||
|
||
instance HasLetDefs Application where | ||
letDefs' acc Application {..} = letDefs' (letDefs' acc _appLeft) _appRight | ||
|
||
instance HasLetDefs Function where | ||
letDefs' acc Function {..} = letDefs' (letDefs' acc _functionLeft) _functionRight | ||
|
||
instance HasLetDefs FunctionParameter where | ||
letDefs' acc FunctionParameter {..} = letDefs' acc _paramType | ||
|
||
instance HasLetDefs Let where | ||
letDefs' acc x@Let {..} = x : letDefs' (letDefs' acc _letExpression) _letClauses | ||
|
||
instance HasLetDefs LetClause where | ||
letDefs' acc = \case | ||
LetFunDef x -> letDefs' acc x | ||
LetMutualBlock x -> letDefs' acc x | ||
|
||
instance HasLetDefs SimpleLambda where | ||
letDefs' acc SimpleLambda {..} = letDefs' (letDefs' acc _slambdaBinder) _slambdaBody | ||
|
||
instance HasLetDefs SimpleBinder where | ||
letDefs' acc SimpleBinder {..} = letDefs' acc _sbinderType | ||
|
||
instance HasLetDefs Lambda where | ||
letDefs' acc Lambda {..} = letDefs' (letDefs' acc _lambdaType) _lambdaClauses | ||
|
||
instance HasLetDefs LambdaClause where | ||
letDefs' acc LambdaClause {..} = letDefs' (letDefs' acc _lambdaBody) _lambdaPatterns | ||
|
||
instance HasLetDefs PatternArg where | ||
letDefs' acc PatternArg {..} = letDefs' acc _patternArgPattern | ||
|
||
instance HasLetDefs Pattern where | ||
letDefs' acc = \case | ||
PatternVariable {} -> acc | ||
PatternConstructorApp x -> letDefs' acc x | ||
PatternWildcardConstructor {} -> acc | ||
|
||
instance HasLetDefs ConstructorApp where | ||
letDefs' acc ConstructorApp {..} = letDefs' (letDefs' acc _constrAppType) _constrAppParameters | ||
|
||
instance HasLetDefs Case where | ||
letDefs' acc Case {..} = letDefs' (letDefs' acc _caseExpression) _caseBranches | ||
|
||
instance HasLetDefs CaseBranch where | ||
letDefs' acc CaseBranch {..} = letDefs' acc _caseBranchExpression | ||
|
||
instance HasLetDefs MutualBlockLet where | ||
letDefs' acc MutualBlockLet {..} = letDefs' acc _mutualLet | ||
|
||
instance HasLetDefs MutualBlock where | ||
letDefs' acc MutualBlock {..} = letDefs' acc _mutualStatements | ||
|
||
instance HasLetDefs MutualStatement where | ||
letDefs' acc = \case | ||
StatementInductive x -> letDefs' acc x | ||
StatementFunction x -> letDefs' acc x | ||
StatementAxiom x -> letDefs' acc x | ||
|
||
instance HasLetDefs InductiveDef where | ||
letDefs' acc InductiveDef {..} = letDefs' (letDefs' (letDefs' acc _inductiveType) _inductiveConstructors) _inductiveParameters | ||
|
||
instance HasLetDefs InductiveParameter where | ||
letDefs' acc InductiveParameter {..} = letDefs' acc _inductiveParamType | ||
|
||
instance HasLetDefs ConstructorDef where | ||
letDefs' acc ConstructorDef {..} = letDefs' acc _inductiveConstructorType | ||
|
||
instance HasLetDefs FunctionDef where | ||
letDefs' acc FunctionDef {..} = letDefs' (letDefs' (letDefs' acc _funDefType) _funDefBody) _funDefArgsInfo | ||
|
||
instance HasLetDefs ArgInfo where | ||
letDefs' acc ArgInfo {..} = letDefs' acc _argInfoDefault | ||
|
||
instance HasLetDefs AxiomDef where | ||
letDefs' acc AxiomDef {..} = letDefs' acc _axiomType |