mirror of
https://github.com/anoma/juvix.git
synced 2024-08-17 04:01:05 +03:00
This PR adds a target for our Makefile to run benchmarks using hyperfine. We run different commands which can be easily modified in bench/hyperfine/Makefile. ``` make hyperfine-benchmarks ``` After running this on your terminal, checkout the generated file bench/hyperfine/README.md for the results. The results below are the runs using the following module. ``` module fibo; import Stdlib.Prelude open; fib : Nat → Nat → Nat → Nat | zero x1 _ := x1 | (suc n) x1 x2 := fib n x2 (x1 + x2); fibonacci (n : Nat) : Nat := fib n 0 1; main : IO := printNatLn (fibonacci 50); ``` (For now, I got the following on my machine (ran in about 5min or less) Darwin Jonathans-MacBook-Pro-2.local 22.6.0 Darwin Kernel Version 22.6.0: Fri Sep 15 13:41:28 PDT 2023; root:xnu-8796.141.3.700.8~1/RELEASE_ARM64_T6020 arm64 arm) - The binary without the version below is the latest commit on main. # Hyperfine Benchmarks ## dev parse | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `juvix-v0.4.3 dev parse fibo.juvix` | 184.3 ± 5.4 | 178.5 | 193.2 | 1.06 ± 0.04 | | `juvix-v0.5.0 dev parse fibo.juvix` | 184.7 ± 6.9 | 179.2 | 201.3 | 1.06 ± 0.05 | | `juvix-v0.5.1 dev parse fibo.juvix` | 174.2 ± 5.4 | 167.9 | 181.0 | 1.00 | | `juvix-v0.5.2 dev parse fibo.juvix` | 181.3 ± 1.6 | 179.5 | 184.1 | 1.04 ± 0.03 | | `juvix-v0.5.3 dev parse fibo.juvix` | 1185.8 ± 5.7 | 1178.4 | 1197.3 | 6.81 ± 0.21 | | `juvix-v0.5.4 dev parse fibo.juvix` | 1308.4 ± 6.9 | 1297.6 | 1319.3 | 7.51 ± 0.23 | | `juvix dev parse fibo.juvix` | 1311.0 ± 5.5 | 1303.2 | 1318.5 | 7.53 ± 0.23 | ## dev highlight | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `juvix-v0.4.3 dev highlight fibo.juvix` | 770.2 ± 67.5 | 742.9 | 961.6 | 1.01 ± 0.09 | | `juvix-v0.5.0 dev highlight fibo.juvix` | 762.7 ± 11.8 | 749.9 | 787.2 | 1.00 | | `juvix-v0.5.1 dev highlight fibo.juvix` | 849.3 ± 9.3 | 836.5 | 863.9 | 1.11 ± 0.02 | | `juvix-v0.5.2 dev highlight fibo.juvix` | 873.5 ± 21.1 | 855.2 | 918.9 | 1.15 ± 0.03 | | `juvix-v0.5.3 dev highlight fibo.juvix` | 2035.9 ± 69.5 | 1946.9 | 2125.4 | 2.67 ± 0.10 | | `juvix-v0.5.4 dev highlight fibo.juvix` | 2218.0 ± 57.3 | 2169.5 | 2316.4 | 2.91 ± 0.09 | | `juvix dev highlight fibo.juvix` | 2206.5 ± 55.9 | 2150.4 | 2296.6 | 2.89 ± 0.09 | ## typecheck | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `juvix-v0.4.3 typecheck fibo.juvix` | 684.1 ± 5.1 | 674.1 | 691.0 | 1.00 | | `juvix-v0.5.0 typecheck fibo.juvix` | 695.9 ± 14.2 | 679.0 | 720.6 | 1.02 ± 0.02 | | `juvix-v0.5.1 typecheck fibo.juvix` | 808.5 ± 18.2 | 780.8 | 848.6 | 1.18 ± 0.03 | | `juvix-v0.5.2 typecheck fibo.juvix` | 816.0 ± 13.9 | 802.3 | 846.3 | 1.19 ± 0.02 | | `juvix-v0.5.3 typecheck fibo.juvix` | 1934.3 ± 29.0 | 1907.3 | 1992.1 | 2.83 ± 0.05 | | `juvix-v0.5.4 typecheck fibo.juvix` | 2106.8 ± 19.6 | 2075.6 | 2138.9 | 3.08 ± 0.04 | | `juvix typecheck fibo.juvix` | 2135.3 ± 29.9 | 2107.4 | 2183.2 | 3.12 ± 0.05 | ## compile -o /dev/null | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `juvix-v0.4.3 compile -o /dev/null fibo.juvix` | 754.3 ± 4.9 | 745.2 | 759.8 | 1.00 ± 0.01 | | `juvix-v0.5.0 compile -o /dev/null fibo.juvix` | 752.6 ± 3.9 | 745.2 | 757.6 | 1.00 | | `juvix-v0.5.1 compile -o /dev/null fibo.juvix` | 845.4 ± 5.7 | 837.6 | 857.0 | 1.12 ± 0.01 | | `juvix-v0.5.2 compile -o /dev/null fibo.juvix` | 883.7 ± 15.7 | 864.5 | 918.3 | 1.17 ± 0.02 | | `juvix-v0.5.3 compile -o /dev/null fibo.juvix` | 1990.8 ± 12.5 | 1975.0 | 2010.4 | 2.65 ± 0.02 | | `juvix-v0.5.4 compile -o /dev/null fibo.juvix` | 2193.9 ± 5.6 | 2182.7 | 2200.5 | 2.91 ± 0.02 | | `juvix compile -o /dev/null fibo.juvix` | 2197.4 ± 11.6 | 2185.0 | 2226.0 | 2.92 ± 0.02 | ## eval | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `juvix-v0.4.3 eval fibo.juvix` | 680.9 ± 5.4 | 669.7 | 687.1 | 1.00 | | `juvix-v0.5.0 eval fibo.juvix` | 681.7 ± 5.0 | 675.0 | 689.8 | 1.00 ± 0.01 | | `juvix-v0.5.1 eval fibo.juvix` | 772.7 ± 2.7 | 769.0 | 777.9 | 1.13 ± 0.01 | | `juvix-v0.5.2 eval fibo.juvix` | 796.1 ± 2.7 | 791.9 | 799.5 | 1.17 ± 0.01 | | `juvix-v0.5.3 eval fibo.juvix` | 1902.2 ± 6.5 | 1889.6 | 1913.2 | 2.79 ± 0.02 | | `juvix-v0.5.4 eval fibo.juvix` | 2101.3 ± 5.9 | 2093.1 | 2112.1 | 3.09 ± 0.03 | | `juvix eval fibo.juvix` | 2111.1 ± 17.4 | 2085.5 | 2148.3 | 3.10 ± 0.04 | --------- Co-authored-by: Paul Cadman <git@paulcadman.dev>
267 lines
6.5 KiB
Makefile
267 lines
6.5 KiB
Makefile
SHELL := /bin/bash
|
|
PWD=$(CURDIR)
|
|
PREFIX="$(PWD)/.stack-work/prefix"
|
|
UNAME := $(shell uname)
|
|
EXAMPLEMILESTONE=examples/milestone
|
|
EXAMPLEHTMLOUTPUT=docs/examples/html
|
|
EXAMPLES= Collatz/Collatz.juvix \
|
|
Fibonacci/Fibonacci.juvix \
|
|
Hanoi/Hanoi.juvix \
|
|
HelloWorld/HelloWorld.juvix \
|
|
PascalsTriangle/PascalsTriangle.juvix \
|
|
TicTacToe/CLI/TicTacToe.juvix \
|
|
Bank/Bank.juvix \
|
|
Tutorial/Tutorial.juvix
|
|
|
|
DEMO_EXAMPLE=examples/demo/Demo.juvix
|
|
|
|
MAKEAUXFLAGS?=-s
|
|
MAKE=make ${MAKEAUXFLAGS}
|
|
METAFILES:=README.md \
|
|
CHANGELOG.md \
|
|
CONTRIBUTING.md \
|
|
LICENSE.md
|
|
|
|
STACKFLAGS?=--jobs $(THREADS)
|
|
STACKTESTFLAGS?=--ta --hide-successes --ta --ansi-tricks=false --ta "+RTS -N -RTS"
|
|
SMOKEFLAGS?=--color --diff=git
|
|
STACK?=stack
|
|
|
|
JUVIXBIN?=juvix
|
|
|
|
ifeq ($(UNAME), Darwin)
|
|
THREADS := $(shell sysctl -n hw.logicalcpu)
|
|
else ifeq ($(UNAME), Linux)
|
|
THREADS := $(shell nproc)
|
|
else
|
|
THREADS := $(shell echo %NUMBER_OF_PROCESSORS%)
|
|
endif
|
|
|
|
all: build
|
|
|
|
clean: clean-runtime
|
|
@${STACK} clean --full
|
|
@rm -rf .hie
|
|
|
|
.PHONY: clean-hard
|
|
clean-hard: clean
|
|
@git clean -fdx
|
|
|
|
.PHONY: clean-runtime
|
|
clean-runtime: clean-juvix-build
|
|
@cd runtime && ${MAKE} clean
|
|
|
|
.PHONY: clean-juvix-build
|
|
clean-juvix-build:
|
|
@find . -type d -name '.juvix-build' | xargs rm -rf
|
|
|
|
repl:
|
|
@${STACK} ghci Juvix:lib ${STACKFLAGS}
|
|
|
|
# -- EXAMPLES HTML OUTPUT
|
|
|
|
.PHONY: html-examples
|
|
html-examples: $(EXAMPLES)
|
|
|
|
$(EXAMPLES):
|
|
$(eval OUTPUTDIR=$(EXAMPLEHTMLOUTPUT)/$(dir $@))
|
|
@mkdir -p ${OUTPUTDIR}
|
|
@${JUVIXBIN} html $(EXAMPLEMILESTONE)/$@ --output-dir=$(CURDIR)/${OUTPUTDIR}
|
|
|
|
.PHONY: demo-example
|
|
demo-example:
|
|
$(eval OUTPUTDIR=$(EXAMPLEHTMLOUTPUT)/Demo)
|
|
@mkdir -p ${OUTPUTDIR}
|
|
@${JUVIXBIN} html $(DEMO_EXAMPLE) --output-dir=$(CURDIR)/${OUTPUTDIR}
|
|
|
|
.PHONY : haddock
|
|
haddock :
|
|
@cabal --docdir=docs/ --htmldir=docs/ haddock --enable-documentation
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# -- Codebase Health
|
|
# ------------------------------------------------------------------------------
|
|
|
|
ORMOLU?=${STACK} exec -- ormolu
|
|
ORMOLUFILES = $(shell git ls-files '*.hs' '*.hs-boot' | grep -v '^contrib/')
|
|
ORMOLUFLAGS?=--no-cabal
|
|
ORMOLUMODE?=inplace
|
|
|
|
.PHONY: ormolu
|
|
ormolu:
|
|
@${ORMOLU} ${ORMOLUFLAGS} \
|
|
--ghc-opt -XStandaloneDeriving \
|
|
--ghc-opt -XUnicodeSyntax \
|
|
--ghc-opt -XDerivingStrategies \
|
|
--ghc-opt -XMultiParamTypeClasses \
|
|
--ghc-opt -XTemplateHaskell \
|
|
--ghc-opt -XImportQualifiedPost \
|
|
--mode ${ORMOLUMODE} \
|
|
$(ORMOLUFILES)
|
|
|
|
.PHONY: format
|
|
format:
|
|
@${MAKE} clang-format
|
|
@${MAKE} ormolu
|
|
|
|
.PHONY: clang-format
|
|
clang-format:
|
|
@cd runtime && ${MAKE} format
|
|
|
|
JUVIX_PACKAGES_IN_REPO=$(shell find \
|
|
./examples \
|
|
./tests/positive \
|
|
./tests/negative \
|
|
-type d \( -name ".juvix-build" -o -name "FancyPaths" \) -prune -o \
|
|
-type f -name 'Package.juvix' -print \
|
|
| awk -F'/Package.juvix' '{print $$1}' | sort -u)
|
|
|
|
JUVIXFORMATFLAGS?=--in-place
|
|
JUVIXTYPECHECKFLAGS?=--only-errors
|
|
|
|
.PHONY: format-juvix-files
|
|
format-juvix-files:
|
|
@for p in $(JUVIX_PACKAGES_IN_REPO); do \
|
|
${JUVIXBIN} format $(JUVIXFORMATFLAGS) "$$p" > /dev/null 2>&1; \
|
|
exit_code=$$?; \
|
|
if [ $$exit_code -eq 0 ]; then \
|
|
echo "[OK] $$p is formatted"; \
|
|
elif [[ $$exit_code -ne 0 && "$$p" == *"tests/"* ]]; then \
|
|
echo "[CONTINUE] $$p is in tests directory."; \
|
|
else \
|
|
echo "[FAIL] $$p formatting failed" && exit 1; \
|
|
fi; \
|
|
done;
|
|
|
|
.PHONY: check-format-juvix-files
|
|
check-format-juvix-files:
|
|
@JUVIXFORMATFLAGS=--check ${MAKE} format-juvix-files
|
|
|
|
JUVIXEXAMPLEFILES=$(shell find ./examples \
|
|
-type d \( -name ".juvix-build" \) -prune -o \
|
|
-name "*.juvix" -print)
|
|
|
|
.PHONY: typecheck-juvix-examples
|
|
typecheck-juvix-examples:
|
|
@for file in $(JUVIXEXAMPLEFILES); do \
|
|
${JUVIXBIN} typecheck "$$file" $(JUVIXTYPECHECKFLAGS); \
|
|
exit_code=$$?; \
|
|
if [ $$exit_code -eq 0 ]; then \
|
|
echo "[OK] $$file typechecks"; \
|
|
else \
|
|
echo "[FAIL] Typecking failed for $$file" && exit 1; \
|
|
fi; \
|
|
done
|
|
|
|
.PHONY: check-ormolu
|
|
check-ormolu: export ORMOLUMODE = check
|
|
check-ormolu:
|
|
@${MAKE} ormolu
|
|
|
|
PRECOMMIT := $(shell command -v pre-commit 2> /dev/null)
|
|
|
|
.PHONY : install-pre-commit
|
|
install-pre-commit :
|
|
@$(if $(PRECOMMIT),, pip install pre-commit)
|
|
|
|
.PHONY : pre-commit
|
|
pre-commit :
|
|
@pre-commit run --all-files
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# -- Build-Install-Test-Release
|
|
# ------------------------------------------------------------------------------
|
|
|
|
.PHONY: check-only
|
|
check-only:
|
|
@${MAKE} build \
|
|
&& ${MAKE} install \
|
|
&& ${MAKE} test \
|
|
&& ${MAKE} smoke \
|
|
&& ${MAKE} check-format-juvix-files \
|
|
&& ${MAKE} typecheck-juvix-examples \
|
|
&& ${MAKE} check-ormolu \
|
|
&& export SKIP=ormolu,format-juvix-examples,typecheck-juvix-examples \
|
|
&& ${MAKE} pre-commit
|
|
|
|
.PHONY: check
|
|
check: clean
|
|
@${MAKE} check-only
|
|
|
|
.PHONY : bench
|
|
bench: runtime submodules
|
|
@${STACK} bench ${STACKFLAGS}
|
|
|
|
# -- Build requirements
|
|
|
|
.PHONY: submodules
|
|
submodules:
|
|
@git submodule sync
|
|
@git submodule update --init --recursive
|
|
|
|
.PHONY: build
|
|
build: submodules runtime
|
|
@${STACK} build ${STACKFLAGS}
|
|
|
|
.PHONY: fast-build
|
|
fast-build: submodules runtime
|
|
@${STACK} build --fast ${STACKFLAGS}
|
|
|
|
.PHONY: runtime
|
|
runtime:
|
|
cd runtime && make -j 4 -s
|
|
|
|
# -- Install
|
|
|
|
.PHONY : install
|
|
install: runtime submodules
|
|
@${STACK} install ${STACKFLAGS}
|
|
|
|
.PHONY : fast-install
|
|
fast-install: runtime submodules
|
|
@${STACK} install --fast ${STACKFLAGS}
|
|
|
|
# -- Testing
|
|
|
|
.PHONY : test
|
|
test: build runtime submodules
|
|
@${STACK} test ${STACKFLAGS} ${STACKTESTFLAGS}
|
|
|
|
.PHONY : fast-test
|
|
fast-test: fast-build
|
|
@${STACK} test --fast ${STACKFLAGS} ${STACKTESTFLAGS}
|
|
|
|
.PHONY : test-skip-slow
|
|
test-skip-slow:
|
|
@${STACK} test ${STACKFLAGS} ${STACKTESTFLAGS} --ta '-p "! /slow tests/"'
|
|
|
|
.PHONY : fast-test-skip-slow
|
|
fast-test-skip-slow:
|
|
@${STACK} test --fast ${STACKFLAGS} ${STACKTESTFLAGS} --ta '-p "! /slow tests/"'
|
|
|
|
SMOKE := $(shell command -v smoke 2> /dev/null)
|
|
SHA256SUM := $(shell command -v sha256sum 2> /dev/null)
|
|
|
|
.PHONY : smoke-only
|
|
smoke-only:
|
|
@$(if $(SMOKE),, $(error "Smoke not found, please install it from https://github.com/jonaprieto/smoke"))
|
|
@$(if $(SHA256SUM),, $(error "sha256sum not found, please install the GNU coreutils package (e.g {apt, brew} install coreutils)"))
|
|
@smoke $(shell find tests -name '*.smoke.yaml')
|
|
|
|
.PHONY : smoke
|
|
smoke: install submodules
|
|
@${MAKE} smoke-only
|
|
|
|
# -- Release
|
|
|
|
.PHONY : changelog
|
|
changelog :
|
|
@github_changelog_generator
|
|
|
|
HYPERFINEBIN := $(shell command -v hyperfine 2> /dev/null)
|
|
|
|
.PHONY : hyperfine-benchmarks
|
|
hyperfine-benchmarks:
|
|
@$(if $(HYPERFINEBIN),, $(error "hyperfine not found, please install it using cargo or from https://github.com/sharkdp/hyperfine"))
|
|
cd bench/hyperfine && ${MAKE}
|