-
Notifications
You must be signed in to change notification settings - Fork 8
experiment: contextual dot + implicits #404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
* First pass * Another pass * Fix stragglers * Fix more stragglers * Apply suggestions from code review Co-authored-by: Christoph <[email protected]> Co-authored-by: Claudio Russo <[email protected]> * Apply suggestions from code review Co-authored-by: Claudio Russo <[email protected]> * Various fixes * Apply suggestions from code review Co-authored-by: Claudio Russo <[email protected]> * Fix * Update API lockfile --------- Co-authored-by: Christoph <[email protected]> Co-authored-by: Claudio Russo <[email protected]>
…ristoph/implicits
✨ Documentation preview for d90dcc7:
|
Benchmark Resultsbench/ArrayBuilding.bench.mo
|
1000 | 100000 | 1000000 | |
---|---|---|---|
List | 548_233 |
48_324_535 |
478_161_875 |
Buffer | 342_005 |
33_903_435 |
339_003_650 |
pure/List | 302_135 |
30_003_590 |
300_055_972 |
VarArray ?T | 180_526 |
17_802_956 |
178_003_171 |
VarArray T | 160_813 |
15_803_243 |
158_003_458 |
Array (baseline) | 42_695 |
4_003_125 |
40_003_340 |
Heap
1000 | 100000 | 1000000 | |
---|---|---|---|
List | 272 B |
272 B |
272 B |
Buffer | 272 B |
272 B |
272 B |
pure/List | 272 B |
272 B |
272 B |
VarArray ?T | 272 B |
272 B |
272 B |
VarArray T | 272 B |
272 B |
272 B |
Array (baseline) | 272 B |
272 B |
272 B |
Garbage Collection
1000 | 100000 | 1000000 | |
---|---|---|---|
List | 10.05 KiB |
797.56 KiB |
7.67 MiB |
Buffer | 8.71 KiB |
782.15 KiB |
7.63 MiB |
pure/List | 19.95 KiB |
1.91 MiB |
19.07 MiB |
VarArray ?T | 8.24 KiB |
781.68 KiB |
7.63 MiB |
VarArray T | 8.23 KiB |
781.67 KiB |
7.63 MiB |
Array (baseline) | 4.3 KiB |
391.02 KiB |
3.82 MiB |
bench/FromIters.bench.mo $({\color{gray}0\%})$
Benchmarking the fromIter functions
Columns describe the number of elements in the input iter.
Instructions:
Heap:
Stable Memory:
Garbage Collection:
Instructions
100 | 10_000 | 100_000 | |
---|---|---|---|
Array.fromIter | 48_764 |
4_712_025 |
47_103_135 |
List.fromIter | 31_698 |
3_061_541 |
30_603_553 |
List.fromIter . Iter.reverse | 50_297 |
4_832_563 |
48_305_477 |
Heap
100 | 10_000 | 100_000 | |
---|---|---|---|
Array.fromIter | 272 B |
272 B |
272 B |
List.fromIter | 272 B |
272 B |
272 B |
List.fromIter . Iter.reverse | 272 B |
272 B |
272 B |
Garbage Collection
100 | 10_000 | 100_000 | |
---|---|---|---|
Array.fromIter | 2.76 KiB |
234.79 KiB |
2.29 MiB |
List.fromIter | 3.51 KiB |
312.88 KiB |
3.05 MiB |
List.fromIter . Iter.reverse | 5.11 KiB |
469.17 KiB |
4.58 MiB |
bench/ListBufferNewArray.bench.mo $({\color{gray}0\%})$
List vs. Buffer for creating known-size arrays
Performance comparison between List and Buffer for creating a new array.
Instructions:
Heap:
Stable Memory:
Garbage Collection:
Instructions
0 (baseline) | 1 | 5 | 10 | 100 (for loop) | |
---|---|---|---|---|---|
List | 1_547 |
2_916 |
9_046 |
13_948 |
74_564 |
pure/List | 1_247 |
1_355 |
2_439 |
3_801 |
31_868 |
Buffer | 2_119 |
2_271 |
3_518 |
5_085 |
36_640 |
Heap
0 (baseline) | 1 | 5 | 10 | 100 (for loop) | |
---|---|---|---|---|---|
List | 272 B |
272 B |
272 B |
272 B |
272 B |
pure/List | 272 B |
272 B |
272 B |
272 B |
272 B |
Buffer | 272 B |
272 B |
272 B |
272 B |
272 B |
Garbage Collection
0 (baseline) | 1 | 5 | 10 | 100 (for loop) | |
---|---|---|---|---|---|
List | 576 B |
616 B |
776 B |
884 B |
1.93 KiB |
pure/List | 360 B |
380 B |
460 B |
560 B |
2.3 KiB |
Buffer | 856 B |
864 B |
896 B |
936 B |
1.62 KiB |
bench/PriorityQueues.bench.mo $({\color{gray}0\%})$
Different priority queue implementations
_Compare the performance of the following priority queue implementations:
-
PriorityQueue
: Binary heap implementation overList
. -
PriorityQueueSet
: Wrapper overSet<(T, Nat)>
._
Instructions:
Heap:
Stable Memory:
Garbage Collection:
Instructions
A) PriorityQueue | B) PriorityQueueSet | |
---|---|---|
1.) 100000 operations (push:pop = 1:1) | 597_528_283 |
522_729_861 |
2.) 100000 operations (push:pop = 2:1) | 742_952_999 |
809_693_415 |
3.) 100000 operations (push:pop = 10:1) | 357_911_737 |
873_181_028 |
4.) 100000 operations (only push) | 192_422_882 |
886_824_792 |
5.) 50000 pushes, then 50000 pops | 776_632_572 |
961_776_534 |
6.) 50000 pushes, then 25000 "pop;push"es | 529_475_053 |
922_137_111 |
Heap
A) PriorityQueue | B) PriorityQueueSet | |
---|---|---|
1.) 100000 operations (push:pop = 1:1) | 272 B |
272 B |
2.) 100000 operations (push:pop = 2:1) | 272 B |
272 B |
3.) 100000 operations (push:pop = 10:1) | 272 B |
272 B |
4.) 100000 operations (only push) | 272 B |
272 B |
5.) 50000 pushes, then 50000 pops | 272 B |
272 B |
6.) 50000 pushes, then 25000 "pop;push"es | 272 B |
272 B |
Garbage Collection
A) PriorityQueue | B) PriorityQueueSet | |
---|---|---|
1.) 100000 operations (push:pop = 1:1) | 15.03 MiB |
17.43 MiB |
2.) 100000 operations (push:pop = 2:1) | 19.73 MiB |
19.32 MiB |
3.) 100000 operations (push:pop = 10:1) | 8.67 MiB |
12.64 MiB |
4.) 100000 operations (only push) | 3.87 MiB |
9.96 MiB |
5.) 50000 pushes, then 50000 pops | 22.03 MiB |
26.2 MiB |
6.) 50000 pushes, then 25000 "pop;push"es | 14.22 MiB |
18.44 MiB |
bench/PureListStackSafety.bench.mo $({\color{red}+0.00\%})$
List Stack safety
Check stack-safety of the following pure/List
-related functions.
Instructions:
Heap:
Stable Memory:
Garbage Collection:
Instructions
pure/List.split | 24_602_524 |
pure/List.all | 7_901_014 |
pure/List.any | 8_001_390 |
pure/List.map | 23_103_767 |
pure/List.filter | 21_104_188 |
pure/List.filterMap | 27_404_742 |
pure/List.partition | 21_304_994 |
pure/List.join | 33_105_326 |
pure/List.flatten | 24_805_667 |
pure/List.take | 24_605_664 |
pure/List.drop | 9_904_119 |
pure/List.foldRight | 19_105_768 |
pure/List.merge | 31_808_584 |
pure/List.chunks | 51_510_344 |
pure/Queue | 142_662_546 |
Heap
pure/List.split | 272 B |
pure/List.all | 272 B |
pure/List.any | 272 B |
pure/List.map | 272 B |
pure/List.filter | 272 B |
pure/List.filterMap | 272 B |
pure/List.partition | 272 B |
pure/List.join | 272 B |
pure/List.flatten | 272 B |
pure/List.take | 272 B |
pure/List.drop | 272 B |
pure/List.foldRight | 272 B |
pure/List.merge | 272 B |
pure/List.chunks | 272 B |
pure/Queue | 272 B |
Garbage Collection
pure/List.split | 3.05 MiB |
pure/List.all | 328 B |
pure/List.any | 328 B |
pure/List.map | 3.05 MiB |
pure/List.filter | 3.05 MiB |
pure/List.filterMap | 3.05 MiB |
pure/List.partition | 3.05 MiB |
pure/List.join | 3.05 MiB |
pure/List.flatten | 3.05 MiB |
pure/List.take | 3.05 MiB |
pure/List.drop | 328 B |
pure/List.foldRight | 1.53 MiB |
pure/List.merge | 4.58 MiB |
pure/List.chunks | 7.63 MiB |
pure/Queue | 18.31 MiB |
bench/Queues.bench.mo $({\color{gray}0\%})$
Different queue implementations
Compare the performance of the following queue implementations:
-
pure/Queue
: The default immutable double-ended queue implementation.- Pros: Good amortized performance, meaning that the average cost of operations is low
O(1)
. - Cons: In worst case, an operation can take
O(size)
time rebuilding the queue as demonstrated in thePop front 2 elements
scenario.
- Pros: Good amortized performance, meaning that the average cost of operations is low
-
pure/RealTimeQueue
- Pros: Every operation is guaranteed to take at most
O(1)
time and space. - Cons: Poor amortized performance: Instruction cost is on average 3x for pop and 8x for push compared to
pure/Queue
.
- Pros: Every operation is guaranteed to take at most
- mutable
Queue
- Pros: Also
O(1)
guarantees with a lower constant factor thanpure/RealTimeQueue
. Amortized performance is comparable topure/Queue
. - Cons: It is mutable and cannot be used in
shared
types (not shareable).
- Pros: Also
Instructions:
Heap:
Stable Memory:
Garbage Collection:
Instructions
pure/Queue | pure/RealTimeQueue | mutable Queue | |
---|---|---|---|
Initialize with 2 elements | 3_092 |
2_304 |
3_040 |
Push 500 elements | 90_713 |
744_219 |
219_284 |
Pop front 2 elements | 86_966 |
4_446 |
3_847 |
Pop 150 front&back | 92_095 |
304_908 |
124_581 |
Heap
pure/Queue | pure/RealTimeQueue | mutable Queue | |
---|---|---|---|
Initialize with 2 elements | 324 B |
300 B |
352 B |
Push 500 elements | 8.08 KiB |
8.17 KiB |
19.8 KiB |
Pop front 2 elements | 240 B |
240 B |
192 B |
Pop 150 front&back | -4.42 KiB |
-492 B |
-11.45 KiB |
Garbage Collection
pure/Queue | pure/RealTimeQueue | mutable Queue | |
---|---|---|---|
Initialize with 2 elements | 508 B |
444 B |
456 B |
Push 500 elements | 10.1 KiB |
137.84 KiB |
344 B |
Pop front 2 elements | 12.19 KiB |
528 B |
424 B |
Pop 150 front&back | 15.61 KiB |
49.66 KiB |
12.1 KiB |
Note: Renamed benchmarks cannot be compared. Refer to the current baseline for manual comparison.
* chore: updates matchers package to mops release (#394) * makes comparison arguments to Map functions implicit * use implicits in tests for Map * make comparison arguments to Set functions implicit * update Set tests to use implicits * remove local bindings, now that we can disambiguate Nat and Int * make equal arguments implicit * rename internal Map and Set size to size_ to avoid clash with contextual dot * Implicit pattern across entire `core` package (#398) * First pass * Another pass * Fix stragglers * Fix more stragglers * Apply suggestions from code review Co-authored-by: Christoph <[email protected]> Co-authored-by: Claudio Russo <[email protected]> * Apply suggestions from code review Co-authored-by: Claudio Russo <[email protected]> * Various fixes * Apply suggestions from code review Co-authored-by: Claudio Russo <[email protected]> * Fix * Update API lockfile --------- Co-authored-by: Christoph <[email protected]> Co-authored-by: Claudio Russo <[email protected]> * rename .size on Queue * add TODO comment * I was using a stale compiler * updates the toolchain to a pre-release * updated mops to pull down draft branch and adjust tests (#399) * feat: Add PriorityQueue (#392) * Partial implementation. * Fix bug and add peek. * Started with tests, and more functions. * Towards more tests, adding SetPriorityQueue. * Completing first implementation, with tests. * Add comments to PriorityQueue.mo * Move set implementation and add benchmark. * Better holes. * Extra benchmark. * More tests. * . * Comments. * Optimization. * Comments for SetWrapper. * Move SetWrapper. * Run format. * . * npm run validate * Fix imports in docstrings. * Add Changelog entry. * Fix Changelog entry. * Remove inefficient push and pop operations (and benchmarks for them). * Move PriorityQueueSet.mo * Fix validation. * Update Changelog. * Update implicits for RealTimeQueue * Update implicits for PriorityQueue * Update API lockfile --------- Co-authored-by: Ryan Vandersmith <[email protected]> Co-authored-by: Claudio Russo <[email protected]> Co-authored-by: Andrei Constantinescu <[email protected]>
No description provided.