Skip to content

Conversation

@Kamirus
Copy link
Contributor

@Kamirus Kamirus commented May 28, 2025

No description provided.

@github-actions
Copy link

github-actions bot commented May 28, 2025

✨ Documentation preview for 35f6501:

https://dfinity.github.io/new-motoko-base/pull/320 (source code)

@github-actions
Copy link

github-actions bot commented May 28, 2025

Benchmark Results

bench/ArrayBuilding.bench.mo $({\color{red}+0.02\%})$

Large known-size array building

Compares performance of different data structures for building arrays of known size.

Instructions: ${\color{red}+0.00\%}$
Heap: ${\color{gray}0\%}$
Stable Memory: ${\color{gray}0\%}$
Garbage Collection: ${\color{red}+0.02\%}$

Instructions

1000 100000 1000000
List 612_133 $({\color{red}+0.02\%})$ 53_731_091 $({\color{red}+0.00\%})$ 531_478_746 $({\color{red}+0.00\%})$
Buffer 367_424 $({\color{gray}0\%})$ 36_403_920 $({\color{gray}0\%})$ 364_004_168 $({\color{gray}0\%})$
pure/List 318_496 $({\color{gray}0\%})$ 31_604_567 $({\color{gray}0\%})$ 316_062_532 $({\color{gray}0\%})$
VarArray ?T 201_911 $({\color{gray}0\%})$ 19_903_407 $({\color{gray}0\%})$ 199_003_655 $({\color{gray}0\%})$
VarArray T 178_245 $({\color{gray}0\%})$ 17_503_741 $({\color{gray}0\%})$ 175_003_989 $({\color{gray}0\%})$
Array (baseline) 44_088 $({\color{gray}0\%})$ 4_103_584 $({\color{gray}0\%})$ 41_003_832 $({\color{gray}0\%})$

Heap

1000 100000 1000000
List 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$
Buffer 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$
pure/List 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$
VarArray ?T 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$
VarArray T 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$
Array (baseline) 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$

Garbage Collection

1000 100000 1000000
List 10.09 KiB $({\color{red}+0.31\%})$ 797.59 KiB $({\color{red}+0.00\%})$ 7.67 MiB $({\color{red}+0.00\%})$
Buffer 8.71 KiB $({\color{gray}0\%})$ 782.15 KiB $({\color{gray}0\%})$ 7.63 MiB $({\color{gray}0\%})$
pure/List 19.95 KiB $({\color{gray}0\%})$ 1.91 MiB $({\color{gray}0\%})$ 19.07 MiB $({\color{gray}0\%})$
VarArray ?T 8.24 KiB $({\color{gray}0\%})$ 781.68 KiB $({\color{gray}0\%})$ 7.63 MiB $({\color{gray}0\%})$
VarArray T 8.23 KiB $({\color{gray}0\%})$ 781.67 KiB $({\color{gray}0\%})$ 7.63 MiB $({\color{gray}0\%})$
Array (baseline) 4.3 KiB $({\color{gray}0\%})$ 391.02 KiB $({\color{gray}0\%})$ 3.82 MiB $({\color{gray}0\%})$
bench/FromIters.bench.mo $({\color{gray}0\%})$

Benchmarking the fromIter functions

Columns describe the number of elements in the input iter.

Instructions: ${\color{gray}0\%}$
Heap: ${\color{gray}0\%}$
Stable Memory: ${\color{gray}0\%}$
Garbage Collection: ${\color{gray}0\%}$

Instructions

100 10_000 100_000
Array.fromIter 53_373 $({\color{gray}0\%})$ 5_152_334 $({\color{gray}0\%})$ 51_503_949 $({\color{gray}0\%})$
List.fromIter 35_436 $({\color{gray}0\%})$ 3_421_823 $({\color{gray}0\%})$ 34_204_824 $({\color{gray}0\%})$
List.fromIter . Iter.reverse 56_149 $({\color{gray}0\%})$ 5_392_962 $({\color{gray}0\%})$ 53_907_349 $({\color{gray}0\%})$

Heap

100 10_000 100_000
Array.fromIter 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$
List.fromIter 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$
List.fromIter . Iter.reverse 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$

Garbage Collection

100 10_000 100_000
Array.fromIter 2.76 KiB $({\color{gray}0\%})$ 234.79 KiB $({\color{gray}0\%})$ 2.29 MiB $({\color{gray}0\%})$
List.fromIter 3.51 KiB $({\color{gray}0\%})$ 312.88 KiB $({\color{gray}0\%})$ 3.05 MiB $({\color{gray}0\%})$
List.fromIter . Iter.reverse 5.11 KiB $({\color{gray}0\%})$ 469.17 KiB $({\color{gray}0\%})$ 4.58 MiB $({\color{gray}0\%})$
No previous results found "/home/runner/work/new-motoko-base/new-motoko-base/.bench/ConcatSlices.bench.json"
bench/List/ConcatSlices.bench.mo $({\color{gray}0\%})$

Create list from two slices

Create two lists of size given in the column, create a new list by concatenating middle halves of each list. Each row is a different concatenation method.

Instructions: ${\color{gray}0\%}$
Heap: ${\color{gray}0\%}$
Stable Memory: ${\color{gray}0\%}$
Garbage Collection: ${\color{gray}0\%}$

Instructions

1000 100000 1000000
List.concatSlices 509_826 43_595_666 430_519_514
List.fromIter . Iter.concat . List.range 824_088 71_354_642 705_147_137
List.addCount_ . List.values_from_ 420_084 33_036_731 323_901_212
List.addCount . List.valuesFrom 436_475 34_636_730 339_900_539

Heap

1000 100000 1000000
List.concatSlices 272 B 272 B 272 B
List.fromIter . Iter.concat . List.range 272 B 272 B 272 B
List.addCount_ . List.values_from_ 272 B 272 B 272 B
List.addCount . List.valuesFrom 272 B 272 B 272 B

Garbage Collection

1000 100000 1000000
List.concatSlices 15.45 KiB 1.17 MiB 11.52 MiB
List.fromIter . Iter.concat . List.range 16.11 KiB 1.18 MiB 11.54 MiB
List.addCount_ . List.values_from_ 16.38 KiB 1.18 MiB 11.56 MiB
List.addCount . List.valuesFrom 16.38 KiB 1.18 MiB 11.56 MiB
No previous results found "/home/runner/work/new-motoko-base/new-motoko-base/.bench/Iteration.bench.json"
bench/List/Iteration.bench.mo $({\color{gray}0\%})$

List iteration

Instructions: ${\color{gray}0\%}$
Heap: ${\color{gray}0\%}$
Stable Memory: ${\color{gray}0\%}$
Garbage Collection: ${\color{gray}0\%}$

Instructions

1000 100000 1000000
while get 270_722 25_107_346 249_653_754
List.values_ while unsafe_next 279_953 25_009_697 247_954_745
while put 364_930 34_420_986 342_689_330
List.values_ while next_set 299_643 26_910_387 266_955_435

Heap

1000 100000 1000000
while get 272 B 272 B 272 B
List.values_ while unsafe_next 272 B 272 B 272 B
while put 272 B 272 B 272 B
List.values_ while next_set 272 B 272 B 272 B

Garbage Collection

1000 100000 1000000
while get 5.19 KiB 399.5 KiB 3.84 MiB
List.values_ while unsafe_next 5.39 KiB 399.7 KiB 3.84 MiB
while put 5.19 KiB 399.5 KiB 3.84 MiB
List.values_ while next_set 5.39 KiB 399.7 KiB 3.84 MiB
bench/ListBufferNewArray.bench.mo $({\color{red}+2.19\%})$

List vs. Buffer for creating known-size arrays

Performance comparison between List and Buffer for creating a new array.

Instructions: ${\color{red}+0.85\%}$
Heap: ${\color{gray}0\%}$
Stable Memory: ${\color{gray}0\%}$
Garbage Collection: ${\color{red}+1.34\%}$

Instructions

0 (baseline) 1 5 10 100 (for loop)
List 1_875 $({\color{red}+6.96\%})$ 3_441 $({\color{red}+3.68\%})$ 10_436 $({\color{red}+1.18\%})$ 15_967 $({\color{red}+0.77\%})$ 82_981 $({\color{red}+0.15\%})$
pure/List 1_450 $({\color{gray}0\%})$ 1_564 $({\color{gray}0\%})$ 2_738 $({\color{gray}0\%})$ 4_205 $({\color{gray}0\%})$ 33_746 $({\color{gray}0\%})$
Buffer 2_378 $({\color{gray}0\%})$ 2_539 $({\color{gray}0\%})$ 3_905 $({\color{gray}0\%})$ 5_612 $({\color{gray}0\%})$ 39_474 $({\color{gray}0\%})$

Heap

0 (baseline) 1 5 10 100 (for loop)
List 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$
pure/List 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$
Buffer 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$ 272 B $({\color{gray}0\%})$

Garbage Collection

0 (baseline) 1 5 10 100 (for loop)
List 608 B $({\color{red}+5.56\%})$ 648 B $({\color{red}+5.19\%})$ 808 B $({\color{red}+4.12\%})$ 916 B $({\color{red}+3.62\%})$ 1.96 KiB $({\color{red}+1.62\%})$
pure/List 360 B $({\color{gray}0\%})$ 380 B $({\color{gray}0\%})$ 460 B $({\color{gray}0\%})$ 560 B $({\color{gray}0\%})$ 2.3 KiB $({\color{gray}0\%})$
Buffer 856 B $({\color{gray}0\%})$ 864 B $({\color{gray}0\%})$ 896 B $({\color{gray}0\%})$ 936 B $({\color{gray}0\%})$ 1.62 KiB $({\color{gray}0\%})$
bench/PureListStackSafety.bench.mo $({\color{gray}0\%})$

List Stack safety

Check stack-safety of the following pure/List-related functions.

Instructions: ${\color{gray}0\%}$
Heap: ${\color{gray}0\%}$
Stable Memory: ${\color{gray}0\%}$
Garbage Collection: ${\color{gray}0\%}$

Instructions

pure/List.split 27_403_700 $({\color{gray}0\%})$
pure/List.all 9_301_156 $({\color{gray}0\%})$
pure/List.any 9_401_585 $({\color{gray}0\%})$
pure/List.map 26_005_117 $({\color{gray}0\%})$
pure/List.filter 24_305_592 $({\color{gray}0\%})$
pure/List.filterMap 30_606_216 $({\color{gray}0\%})$
pure/List.partition 24_706_539 $({\color{gray}0\%})$
pure/List.join 38_606_854 $({\color{gray}0\%})$
pure/List.flatten 29_607_262 $({\color{gray}0\%})$
pure/List.take 27_407_282 $({\color{gray}0\%})$
pure/List.drop 11_004_661 $({\color{gray}0\%})$
pure/List.foldRight 21_806_962 $({\color{gray}0\%})$
pure/List.merge 36_411_001 $({\color{gray}0\%})$
pure/List.chunks 61_513_741 $({\color{gray}0\%})$
pure/Queue 161_571_999 $({\color{gray}0\%})$

Heap

pure/List.split 272 B $({\color{gray}0\%})$
pure/List.all 272 B $({\color{gray}0\%})$
pure/List.any 272 B $({\color{gray}0\%})$
pure/List.map 272 B $({\color{gray}0\%})$
pure/List.filter 272 B $({\color{gray}0\%})$
pure/List.filterMap 272 B $({\color{gray}0\%})$
pure/List.partition 272 B $({\color{gray}0\%})$
pure/List.join 272 B $({\color{gray}0\%})$
pure/List.flatten 272 B $({\color{gray}0\%})$
pure/List.take 272 B $({\color{gray}0\%})$
pure/List.drop 272 B $({\color{gray}0\%})$
pure/List.foldRight 272 B $({\color{gray}0\%})$
pure/List.merge 272 B $({\color{gray}0\%})$
pure/List.chunks 272 B $({\color{gray}0\%})$
pure/Queue 272 B $({\color{gray}0\%})$

Garbage Collection

pure/List.split 3.05 MiB $({\color{gray}0\%})$
pure/List.all 328 B $({\color{gray}0\%})$
pure/List.any 328 B $({\color{gray}0\%})$
pure/List.map 3.05 MiB $({\color{gray}0\%})$
pure/List.filter 3.05 MiB $({\color{gray}0\%})$
pure/List.filterMap 3.05 MiB $({\color{gray}0\%})$
pure/List.partition 3.05 MiB $({\color{gray}0\%})$
pure/List.join 3.05 MiB $({\color{gray}0\%})$
pure/List.flatten 3.05 MiB $({\color{gray}0\%})$
pure/List.take 3.05 MiB $({\color{gray}0\%})$
pure/List.drop 328 B $({\color{gray}0\%})$
pure/List.foldRight 1.53 MiB $({\color{gray}0\%})$
pure/List.merge 4.58 MiB $({\color{gray}0\%})$
pure/List.chunks 7.63 MiB $({\color{gray}0\%})$
pure/Queue 18.31 MiB $({\color{gray}0\%})$
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 the Pop front 2 elements scenario.
  • 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.
  • mutable Queue
    • Pros: Also O(1) guarantees with a lower constant factor than pure/RealTimeQueue. Amortized performance is comparable to pure/Queue.
    • Cons: It is mutable and cannot be used in shared types (not shareable).

Instructions: ${\color{gray}0\%}$
Heap: ${\color{gray}0\%}$
Stable Memory: ${\color{gray}0\%}$
Garbage Collection: ${\color{gray}0\%}$

Instructions

pure/Queue pure/RealTimeQueue mutable Queue
Initialize with 2 elements 3_571 $({\color{gray}0\%})$ 2_592 $({\color{gray}0\%})$ 3_401 $({\color{gray}0\%})$
Push 500 elements 103_492 $({\color{gray}0\%})$ 867_120 $({\color{gray}0\%})$ 243_585 $({\color{gray}0\%})$
Pop front 2 elements 98_792 $({\color{gray}0\%})$ 5_009 $({\color{gray}0\%})$ 4_326 $({\color{gray}0\%})$
Pop 150 front&back 106_545 $({\color{gray}0\%})$ 350_417 $({\color{gray}0\%})$ 140_211 $({\color{gray}0\%})$

Heap

pure/Queue pure/RealTimeQueue mutable Queue
Initialize with 2 elements 324 B $({\color{gray}0\%})$ 300 B $({\color{gray}0\%})$ 352 B $({\color{gray}0\%})$
Push 500 elements 8.08 KiB $({\color{gray}0\%})$ 8.17 KiB $({\color{gray}0\%})$ 19.8 KiB $({\color{gray}0\%})$
Pop front 2 elements 240 B $({\color{gray}0\%})$ 240 B $({\color{gray}0\%})$ 192 B $({\color{gray}0\%})$
Pop 150 front&back -4.42 KiB $({\color{gray}0\%})$ -492 B $({\color{gray}0\%})$ -11.45 KiB $({\color{gray}0\%})$

Garbage Collection

pure/Queue pure/RealTimeQueue mutable Queue
Initialize with 2 elements 508 B $({\color{gray}0\%})$ 444 B $({\color{gray}0\%})$ 456 B $({\color{gray}0\%})$
Push 500 elements 10.1 KiB $({\color{gray}0\%})$ 137.84 KiB $({\color{gray}0\%})$ 344 B $({\color{gray}0\%})$
Pop front 2 elements 12.19 KiB $({\color{gray}0\%})$ 528 B $({\color{gray}0\%})$ 424 B $({\color{gray}0\%})$
Pop 150 front&back 15.61 KiB $({\color{gray}0\%})$ 49.66 KiB $({\color{gray}0\%})$ 12.1 KiB $({\color{gray}0\%})$

Note: Renamed benchmarks cannot be compared. Refer to the current baseline for manual comparison.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants