Open seagreen opened 8 years ago
Has how much makeLenses slows down compilation been researched?
I don't think it has been.
would that be a useful thing for me to look into
Yep! I can think of several questions off the top of my head:
makeLenses
is applied to a record with one field? Two? Ten? Thirty?Note that if you simply compile a module with lenses, the optimiser might remove unused code instead of optimising it further (I don't know whether it's actually possible but it seems plausible), so don't forget to export the derived lenses. Benchmarking can probably be done with bench.
Thanks for the thoughts, this is going on my todo list.
Make an initial experimental repo:
Here are manual lenses: https://github.com/seagreen/microlens-th-experiments/blob/master/plain-lenses/src/Experiment.hs#L121
Here are th lenses: https://github.com/seagreen/microlens-th-experiments/blob/master/th-lenses/src/Experiment.hs#L122
And here are the results: https://github.com/seagreen/microlens-th-experiments/blob/master/results.txt
The test sources are the most boring thing I could think of. 5 data types, each with 20 fields, nothing else (the only exception is the small-data
project which has 5 data types with 1 field each).
I've got some thoughts on the results, but take a look at the code first and let me know what you think.
PS bench
was a great recommendation.
Thanks!
I modified the test to call ghc
on one file instead of stack
(and also to run longer with -L 300
). With 7.10.3 I'm getting that lens generation takes 400ms (and compilation – 1s):
small-data
benchmarking rm -f src/*.hi; rm -f src/*.o; ghc -O src/Experiment.hs
time 160.5 ms (155.7 ms .. 165.3 ms)
no-lenses
benchmarking rm -f src/*.hi; rm -f src/*.o; ghc -O src/Experiment.hs
time 335.8 ms (331.1 ms .. 339.7 ms)
plain-lenses
benchmarking rm -f src/*.hi; rm -f src/*.o; ghc -O src/Experiment.hs
time 1.063 s (1.054 s .. 1.073 s)
th-lenses
benchmarking rm -f src/*.hi; rm -f src/*.o; ghc -O src/Experiment.hs
time 1.457 s (1.437 s .. 1.484 s)
With stack ghc
and GHC 8 lens generation takes the same 400ms, but compilation jumps to 1.3s (might be because of compiling dyn
files too, I don't know how to turn it off):
small-data
benchmarking rm -f src/*.hi; rm -f src/*.o; rm -f src/*.dyn_hi; rm -f src/*.dyn_o; stack ghc --resolver nightly-2016-07-04 -- -O src/Experiment.hs
time 327.5 ms (318.4 ms .. 336.3 ms)
no-lenses
benchmarking rm -f src/*.hi; rm -f src/*.o; rm -f src/*.dyn_hi; rm -f src/*.dyn_o; stack ghc --resolver nightly-2016-07-04 -- -O src/Experiment.hs
time 550.2 ms (537.5 ms .. 564.4 ms)
plain-lenses
benchmarking rm -f src/*.hi; rm -f src/*.o; rm -f src/*.dyn_hi; rm -f src/*.dyn_o; stack ghc --resolver nightly-2016-07-04 -- -O src/Experiment.hs
time 1.324 s (1.317 s .. 1.335 s)
th-lenses
benchmarking rm -f src/*.hi; rm -f src/*.o; rm -f src/*.dyn_hi; rm -f src/*.dyn_o; stack ghc --resolver nightly-2016-07-04 -- -O src/Experiment.hs
time 1.727 s (1.701 s .. 1.763 s)
Interestingly, in your tests the difference between manual and TH lenses is much smaller. Can you rerun them with a bigger -L
? (It controls how many seconds the benchmark will run)
Another thing to do, by the way, is to figure out how the added time depends on the number of fields vs the number of records. Does it matter if the fields are in different records, or not?
Here are my results with -L 300
. The difference between manual and TH lenses stayed small.
benchmarking cd ~/code/mine/microlens-th-experiments/small-data; rm -rf ./.stack-work; stack build
time 2.688 s (2.677 s .. 2.696 s)
1.000 R² (1.000 R² .. 1.000 R²)
mean 2.695 s (2.689 s .. 2.705 s)
std dev 15.70 ms (8.709 ms .. 25.10 ms)
benchmarking cd ~/code/mine/microlens-th-experiments/no-lenses; rm -rf ./.stack-work; stack build
time 2.913 s (2.893 s .. 2.926 s)
1.000 R² (1.000 R² .. 1.000 R²)
mean 2.934 s (2.921 s .. 2.959 s)
std dev 30.07 ms (5.817 ms .. 43.02 ms)
benchmarking cd ~/code/mine/microlens-th-experiments/plain-lenses; rm -rf ./.stack-work; stack build
time 3.778 s (3.732 s .. 3.830 s)
1.000 R² (0.999 R² .. 1.000 R²)
mean 3.756 s (3.745 s .. 3.780 s)
std dev 27.24 ms (14.54 ms .. 42.07 ms)
benchmarking cd ~/code/mine/microlens-th-experiments/th-lenses; rm -rf ./.stack-work; stack build
time 3.985 s (3.967 s .. 4.005 s)
1.000 R² (1.000 R² .. 1.000 R²)
mean 3.979 s (3.973 s .. 3.987 s)
std dev 11.94 ms (7.659 ms .. 15.89 ms)
Want to push up your changes (you've got push access to the repo) and then I can rerun them with an identical setup to you?
Right now the README helpfully suggests that library authors start with
microlens
instead ofmicrolens-platform
and add packages as needed.I'm curious if
microlens-th
is appropriate for library authors, or whether slowing down the library's compile time isn't worth the tradeoff of conveniently deriving lenses. Has how muchmakeLenses
slows down compilation been researched? If it hasn't would that be a useful thing for me to look into and contribute to the README?