Skip to content
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

bump moc #117

Closed
wants to merge 35 commits into from
Closed

bump moc #117

wants to merge 35 commits into from

Conversation

chenyan-dfinity
Copy link
Contributor

@chenyan-dfinity chenyan-dfinity commented Sep 30, 2024

  • moc 0.13 timeout (fixable by increase backoff time)
  • dfx 22, moc 0.12.1 works (sometimes?)
  • dfx 23,24, moc 0.12.1 stale certificate (seem to work under ubuntu)

Copy link

github-actions bot commented Oct 1, 2024

Note
Diffing the performance result against the published result from main branch.
Unchanged benchmarks are omitted.

Map

binary_size generate 1m max mem batch_get 50 batch_put 50 batch_remove 50 upgrade
hashmap 194_189 ($\textcolor{red}{2.24\%}$) 8_202_056_175 ($\textcolor{red}{0.21\%}$) 56_000_256 343_224 ($\textcolor{red}{0.13\%}$) 6_479_018_520 ($\textcolor{red}{0.26\%}$) 368_878 ($\textcolor{red}{0.12\%}$) 10_779_626_429 ($\textcolor{red}{0.48\%}$)
triemap 199_728 ($\textcolor{red}{2.18\%}$) 13_670_187_591 ($\textcolor{red}{0.06\%}$) 68_228_576 252_711 ($\textcolor{red}{0.02\%}$) 657_894 ($\textcolor{red}{0.02\%}$) 648_191 ($\textcolor{red}{0.02\%}$) 15_542_338_034 ($\textcolor{red}{0.28\%}$)
rbtree 190_161 ($\textcolor{red}{2.29\%}$) 7_013_924_711 ($\textcolor{red}{0.07\%}$) 52_000_464 116_424 ($\textcolor{red}{0.07\%}$) 318_397 ($\textcolor{red}{0.02\%}$) 330_303 ($\textcolor{red}{0.02\%}$) 6_995_883_219 ($\textcolor{red}{1.82\%}$)
splay 194_714 ($\textcolor{red}{2.24\%}$) 13_162_352_813 ($\textcolor{red}{0.04\%}$) 48_000_400 631_407 ($\textcolor{red}{0.01\%}$) 663_076 ($\textcolor{red}{0.01\%}$) 928_183 ($\textcolor{red}{0.00\%}$) 4_345_903_658 ($\textcolor{red}{0.86\%}$)
btree 234_445 ($\textcolor{red}{1.79\%}$) 10_227_244_425 ($\textcolor{red}{0.03\%}$) 25_108_416 357_988 ($\textcolor{red}{0.02\%}$) 485_870 ($\textcolor{red}{0.02\%}$) 539_566 ($\textcolor{red}{0.01\%}$) 2_920_276_997 ($\textcolor{red}{2.04\%}$)
zhenya_hashmap 193_036 ($\textcolor{red}{2.19\%}$) 2_361_649_020 ($\textcolor{red}{0.04\%}$) 16_777_504 58_306 ($\textcolor{red}{0.18\%}$) 66_651 ($\textcolor{red}{0.15\%}$) 79_783 ($\textcolor{red}{0.14\%}$) 3_096_626_671 ($\textcolor{red}{2.60\%}$)
btreemap_rs 557_023 ($\textcolor{red}{0.20\%}$) 1_796_610_879 ($\textcolor{red}{0.22\%}$) 27_590_656 73_290 ($\textcolor{green}{-0.01\%}$) 123_186 ($\textcolor{green}{-0.00\%}$) 85_038 ($\textcolor{green}{-0.01\%}$) 3_204_150_781 ($\textcolor{green}{-0.00\%}$)
imrc_hashmap_rs 559_039 ($\textcolor{red}{0.52\%}$) 2_584_010_729 244_908_032 35_538 ($\textcolor{green}{-0.02\%}$) 194_920 ($\textcolor{green}{-0.00\%}$) 93_147 ($\textcolor{green}{-0.01\%}$) 6_272_274_629 ($\textcolor{green}{-0.00\%}$)
hashmap_rs 547_945 ($\textcolor{red}{0.62\%}$) 439_245_801 73_138_176 20_001 ($\textcolor{green}{-0.03\%}$) 24_923 ($\textcolor{green}{-0.03\%}$) 23_236 ($\textcolor{green}{-0.03\%}$) 1_565_610_858 ($\textcolor{green}{-0.00\%}$)

Priority queue

binary_size heapify 1m max mem pop_min 50 put 50 pop_min 50.1 upgrade
heap 171_085 ($\textcolor{red}{2.51\%}$) 5_557_564_416 ($\textcolor{red}{0.05\%}$) 24_000_360 621_765 ($\textcolor{red}{0.01\%}$) 227_300 ($\textcolor{red}{0.03\%}$) 592_705 ($\textcolor{red}{0.02\%}$) 3_245_817_069 ($\textcolor{red}{1.76\%}$)
heap_rs 541_957 ($\textcolor{red}{0.24\%}$) 139_667_629 18_284_544 55_873 ($\textcolor{green}{-0.01\%}$) 21_264 ($\textcolor{green}{-0.03\%}$) 55_758 ($\textcolor{green}{-0.01\%}$) 648_921_182 ($\textcolor{green}{-0.00\%}$)

Growable array

binary_size generate 5k max mem batch_get 500 batch_put 500 batch_remove 500 upgrade
buffer 178_179 ($\textcolor{red}{2.46\%}$) 2_601_297 ($\textcolor{red}{0.01\%}$) 65_652 ($\textcolor{red}{0.01\%}$) 95_582 ($\textcolor{red}{0.08\%}$) 803_552 ($\textcolor{red}{0.01\%}$) 173_582 ($\textcolor{red}{0.04\%}$) 3_156_157 ($\textcolor{red}{2.10\%}$)
vector 176_002 ($\textcolor{red}{2.37\%}$) 1_952_757 ($\textcolor{red}{0.00\%}$) 24_588 ($\textcolor{red}{0.03\%}$) 126_206 ($\textcolor{red}{0.06\%}$) 186_561 ($\textcolor{red}{0.04\%}$) 176_199 ($\textcolor{red}{0.04\%}$) 4_808_803 ($\textcolor{red}{2.86\%}$)
vec_rs 539_845 ($\textcolor{red}{0.25\%}$) 286_776 1_376_256 15_707 ($\textcolor{green}{-0.04\%}$) 28_786 ($\textcolor{green}{-0.02\%}$) 21_546 ($\textcolor{green}{-0.03\%}$) 3_806_204 ($\textcolor{red}{0.01\%}$)

Stable structures

binary_size generate 50k max mem batch_get 50 batch_put 50 batch_remove 50 upgrade
btreemap_rs 557_023 ($\textcolor{red}{0.20\%}$) 76_361_524 ($\textcolor{red}{0.26\%}$) 2_555_904 62_848 ($\textcolor{green}{-0.01\%}$) 95_113 ($\textcolor{green}{-0.01\%}$) 84_043 ($\textcolor{green}{-0.01\%}$) 139_591_425 ($\textcolor{green}{-0.00\%}$)
btreemap_stable_rs 559_365 ($\textcolor{red}{0.23\%}$) 4_564_070_850 2_031_616 2_709_640 ($\textcolor{green}{-0.00\%}$) 5_031_620 ($\textcolor{green}{-0.00\%}$) 8_581_107 ($\textcolor{green}{-0.00\%}$) 729_344
heap_rs 541_957 ($\textcolor{red}{0.24\%}$) 7_049_481 2_293_760 48_382 ($\textcolor{green}{-0.01\%}$) 21_512 ($\textcolor{green}{-0.03\%}$) 48_107 ($\textcolor{green}{-0.01\%}$) 33_629_605 ($\textcolor{green}{-0.00\%}$)
heap_stable_rs 522_462 ($\textcolor{red}{0.25\%}$) 277_865_060 458_752 2_405_446 ($\textcolor{green}{-0.00\%}$) 242_822 ($\textcolor{green}{-0.00\%}$) 2_387_309 ($\textcolor{green}{-0.00\%}$) 729_349
vec_rs 539_845 ($\textcolor{red}{0.25\%}$) 3_077_152 2_293_760 15_707 ($\textcolor{green}{-0.04\%}$) 16_636 ($\textcolor{green}{-0.04\%}$) 15_934 ($\textcolor{green}{-0.04\%}$) 31_301_799 ($\textcolor{red}{0.00\%}$)
vec_stable_rs 522_579 ($\textcolor{red}{0.24\%}$) 63_342_328 ($\textcolor{green}{-0.00\%}$) 458_752 64_869 ($\textcolor{green}{-0.01\%}$) 78_799 ($\textcolor{green}{-0.01\%}$) 84_161 ($\textcolor{green}{-0.01\%}$) 729_343 ($\textcolor{green}{-0.00\%}$)

Statistics

  • binary_size: 1.17% [0.78%, 1.57%]
  • max_mem: 0.02% [-0.04%, 0.09%]
  • cycles: 0.19% [0.09%, 0.29%]

SHA-2

binary_size SHA-256 SHA-512 account_id neuron_id
Motoko 199_291 ($\textcolor{red}{2.89\%}$) 282_867_522 ($\textcolor{red}{5.65\%}$) 262_958_038 ($\textcolor{red}{6.10\%}$) 34_374 ($\textcolor{red}{2.19\%}$) 25_343 ($\textcolor{red}{3.31\%}$)
Rust 541_269 ($\textcolor{green}{-0.11\%}$) 82_781_773 ($\textcolor{green}{-0.00\%}$) 56_787_252 ($\textcolor{green}{-0.00\%}$) 41_000 ($\textcolor{green}{-0.11\%}$) 39_898 ($\textcolor{green}{-0.13\%}$)

Certified map

binary_size generate 10k max mem inc witness upgrade
Motoko 248_064 ($\textcolor{red}{1.82\%}$) 365_594_405 ($\textcolor{green}{-92.16\%}$) 342_396 ($\textcolor{green}{-90.02\%}$) 397_632 ($\textcolor{green}{-28.18\%}$) 267_766 ($\textcolor{green}{-34.36\%}$) 22_437_392 ($\textcolor{green}{-91.82\%}$)
Rust 581_748 ($\textcolor{red}{0.22\%}$) 490_093_124 ($\textcolor{green}{-92.35\%}$) 1_310_720 ($\textcolor{green}{-41.18\%}$) 661_017 ($\textcolor{green}{-35.22\%}$) 219_694 ($\textcolor{green}{-26.33\%}$) 451_141_325 ($\textcolor{green}{-92.51\%}$)

Statistics

  • binary_size: 1.20% [-0.45%, 2.86%]
  • max_mem: -65.60% [-219.78%, 88.59%]
  • cycles: -29.75% [-47.22%, -12.27%]

Basic DAO

binary_size init transfer_token submit_proposal vote_proposal upgrade
Motoko 278_758 ($\textcolor{red}{1.76\%}$) 513_173 ($\textcolor{red}{0.46\%}$) 23_357 ($\textcolor{red}{4.66\%}$) 19_191 ($\textcolor{red}{3.19\%}$) 20_401 ($\textcolor{red}{3.75\%}$) 161_785 ($\textcolor{red}{2.42\%}$)
Rust 856_658 ($\textcolor{red}{1.08\%}$) 505_502 ($\textcolor{green}{-0.19\%}$) 88_807 ($\textcolor{green}{-0.15\%}$) 116_797 ($\textcolor{green}{-0.48\%}$) 111_945 ($\textcolor{green}{-0.36\%}$) 1_478_640 ($\textcolor{green}{-0.32\%}$)

DIP721 NFT

binary_size init mint_token transfer_token upgrade
Motoko 224_935 ($\textcolor{red}{2.06\%}$) 482_026 ($\textcolor{red}{0.18\%}$) 31_119 ($\textcolor{red}{3.03\%}$) 8_891 ($\textcolor{red}{1.45\%}$) 91_908 ($\textcolor{red}{2.31\%}$)
Rust 881_139 ($\textcolor{red}{0.14\%}$) 203_263 ($\textcolor{green}{-0.12\%}$) 301_918 ($\textcolor{green}{-0.38\%}$) 70_807 ($\textcolor{green}{-0.60\%}$) 1_624_865 ($\textcolor{green}{-0.31\%}$)

Statistics

  • binary_size: 1.26% [0.26%, 2.26%]
  • max_mem: no change
  • cycles: 1.03% [0.32%, 1.74%]

Heartbeat

binary_size heartbeat
Motoko 142_267 ($\textcolor{red}{3.71\%}$) 27_506 ($\textcolor{red}{41.01\%}$)
Rust 23_866 ($\textcolor{red}{0.88\%}$) 1_112 ($\textcolor{red}{131.67\%}$)

Timer

binary_size setTimer cancelTimer
Motoko 150_098 ($\textcolor{red}{3.08\%}$) 56_189 ($\textcolor{red}{8.52\%}$) 4_702 ($\textcolor{red}{1.64\%}$)
Rust 504_144 ($\textcolor{red}{0.28\%}$) 63_372 ($\textcolor{green}{-0.01\%}$) 11_676

Statistics

  • binary_size: 1.68% [-7.16%, 10.51%]
  • max_mem: no change
  • cycles: 3.38% [-4.24%, 11.01%]

Garbage Collection

generate 700k max mem batch_get 50 batch_put 50 batch_remove 50
default 1_074_136_336 ($\textcolor{red}{0.56\%}$) 47_793_792 119 119 119
copying 1_074_136_218 ($\textcolor{red}{0.56\%}$) 47_793_792 1_073_873_789 ($\textcolor{red}{0.56\%}$) 1_073_954_095 ($\textcolor{red}{0.56\%}$) 1_073_875_311 ($\textcolor{red}{0.56\%}$)
compacting 1_554_238_605 ($\textcolor{red}{0.56\%}$) 47_793_792 1_200_791_965 ($\textcolor{red}{0.73\%}$) 1_424_078_246 ($\textcolor{red}{0.61\%}$) 1_447_969_756 ($\textcolor{red}{0.60\%}$)
generational 2_326_734_591 ($\textcolor{red}{0.98\%}$) 47_802_256 899_105_682 ($\textcolor{red}{1.92\%}$) 1_214_812 ($\textcolor{red}{0.30\%}$) 1_107_099 ($\textcolor{red}{0.32\%}$)
incremental 29_505_471 ($\textcolor{red}{0.01\%}$) 976_097_724 ($\textcolor{red}{0.00\%}$) 469_026_873 ($\textcolor{green}{-0.61\%}$) 496_491_319 ($\textcolor{green}{-0.20\%}$) 1_282_778_770 ($\textcolor{red}{5.03\%}$)

Actor class

binary size put new bucket put existing bucket get
Map 421_098 ($\textcolor{red}{40.73\%}$) 757_731 ($\textcolor{green}{-6.86\%}$) 16_360 ($\textcolor{red}{1.52\%}$) 16_930 ($\textcolor{red}{1.62\%}$)

Statistics

  • binary_size: no change
  • max_mem: 0.00%
  • cycles: 2.38% [-1.01%, 5.78%]

Publisher & Subscriber

pub_binary_size sub_binary_size subscribe_caller subscribe_callee publish_caller publish_callee
Motoko 165_839 ($\textcolor{red}{2.82\%}$) 150_138 ($\textcolor{red}{3.02\%}$) 32_873 ($\textcolor{red}{14.97\%}$) 12_214 ($\textcolor{red}{2.10\%}$) 27_075 ($\textcolor{red}{18.47\%}$) 6_629 ($\textcolor{red}{2.84\%}$)
Rust 539_139 ($\textcolor{red}{0.60\%}$) 576_928 ($\textcolor{red}{0.54\%}$) 57_754 ($\textcolor{red}{0.46\%}$) 37_782 ($\textcolor{green}{-0.04\%}$) 71_207 ($\textcolor{green}{-0.20\%}$) 42_396 ($\textcolor{green}{-0.12\%}$)

Statistics

  • binary_size: 1.74% [0.14%, 3.34%]
  • max_mem: no change
  • cycles: 4.81% [-0.21%, 9.83%]

Overall Statistics

  • binary_size: 1.28% [0.97%, 1.60%]
  • max_mem: -26.23% [-64.24%, 11.78%]
  • cycles: -2.19% [-4.31%, -0.07%]

Copy link

github-actions bot commented Oct 1, 2024

Note
The flamegraph link only works after you merge.
Unchanged benchmarks are omitted.

Collection libraries

Measure different collection libraries written in both Motoko and Rust.
The library names with _rs suffix are written in Rust; the rest are written in Motoko.
The _stable and _stable_rs suffix represents that the library directly writes the state to stable memory using Region in Motoko and ic-stable-stuctures in Rust.

We use the same random number generator with fixed seed to ensure that all collections contain
the same elements, and the queries are exactly the same. Below we explain the measurements of each column in the table:

  • generate 1m. Insert 1m Nat64 integers into the collection. For Motoko collections, it usually triggers the GC; the rest of the column are not likely to trigger GC.
  • max mem. For Motoko, it reports rts_max_heap_size after generate call; For Rust, it reports the Wasm's memory page * 32Kb.
  • batch_get 50. Find 50 elements from the collection.
  • batch_put 50. Insert 50 elements to the collection.
  • batch_remove 50. Remove 50 elements from the collection.
  • upgrade. Upgrade the canister with the same Wasm module. For non-stable benchmarks, the map state is persisted by serializing and deserializing states into stable memory. For stable benchmarks, the upgrade takes no cycles, as the state is already in the stable memory.

💎 Takeaways

  • The platform only charges for instruction count. Data structures which make use of caching and locality have no impact on the cost.
  • We have a limit on the maximal cycles per round. This means asymptotic behavior doesn't matter much. We care more about the performance up to a fixed N. In the extreme cases, you may see an $O(10000 n\log n)$ algorithm hitting the limit, while an $O(n^2)$ algorithm runs just fine.
  • Amortized algorithms/GC may need to be more eager to avoid hitting the cycle limit on a particular round.
  • Rust costs more cycles to process complicated Candid data, but it is more efficient in performing core computations.

Note

  • The Candid interface of the benchmark is minimal, therefore the serialization cost is negligible in this measurement.
  • Due to the instrumentation overhead and cycle limit, we cannot profile computations with very large collections.
  • The upgrade column uses Candid for serializing stable data. In Rust, you may get better cycle cost by using a different serialization format. Another slowdown in Rust is that ic-stable-structures tends to be slower than the region memory in Motoko.
  • Different library has different ways for persisting data during upgrades, there are mainly three categories:
    • Use stable variable directly in Motoko: zhenya_hashmap, btree, vector
    • Expose and serialize external state (share/unshare in Motoko, candid::Encode in Rust): rbtree, heap, btreemap_rs, hashmap_rs, heap_rs, vector_rs
    • Use pre/post-upgrade hooks to convert data into an array: hashmap, splay, triemap, buffer, imrc_hashmap_rs
  • The stable benchmarks are much more expensive than their non-stable counterpart, because the stable memory API is much more expensive. The benefit is that they get fast upgrade. The upgrade still needs to parse the metadata when initializing the upgraded Wasm module.
  • hashmap uses amortized data structure. When the initial capacity is reached, it has to copy the whole array, thus the cost of batch_put 50 is much higher than other data structures.
  • btree comes from mops.one/stableheapbtreemap.
  • zhenya_hashmap comes from mops.one/map.
  • vector comes from mops.one/vector. Compare with buffer, put has better worst case time and space complexity ($O(\sqrt{n})$ vs $O(n)$); get has a slightly larger constant overhead.
  • hashmap_rs uses the fxhash crate, which is the same as std::collections::HashMap, but with a deterministic hasher. This ensures reproducible result.
  • imrc_hashmap_rs uses the im-rc crate, which is the immutable version hashmap in Rust.

Map

binary_size generate 1m max mem batch_get 50 batch_put 50 batch_remove 50 upgrade
hashmap 194_189 8_202_056_175 56_000_256 343_224 6_479_018_520 368_878 10_779_626_429
triemap 199_728 13_670_187_591 68_228_576 252_711 657_894 648_191 15_542_338_034
rbtree 190_161 7_013_924_711 52_000_464 116_424 318_397 330_303 6_995_883_219
splay 194_714 13_162_352_813 48_000_400 631_407 663_076 928_183 4_345_903_658
btree 234_445 10_227_244_425 25_108_416 357_988 485_870 539_566 2_920_276_997
zhenya_hashmap 193_036 2_361_649_020 16_777_504 58_306 66_651 79_783 3_096_626_671
btreemap_rs 557_023 1_796_610_879 27_590_656 73_290 123_186 85_038 3_204_150_781
imrc_hashmap_rs 559_039 2_584_010_729 244_908_032 35_538 194_920 93_147 6_272_274_629
hashmap_rs 547_945 439_245_801 73_138_176 20_001 24_923 23_236 1_565_610_858

Priority queue

binary_size heapify 1m max mem pop_min 50 put 50 pop_min 50 upgrade
heap 171_085 5_557_564_416 24_000_360 621_765 227_300 592_705 3_245_817_069
heap_rs 541_957 139_667_629 18_284_544 55_873 21_264 55_758 648_921_182

Growable array

binary_size generate 5k max mem batch_get 500 batch_put 500 batch_remove 500 upgrade
buffer 178_179 2_601_297 65_652 95_582 803_552 173_582 3_156_157
vector 176_002 1_952_757 24_588 126_206 186_561 176_199 4_808_803
vec_rs 539_845 286_776 1_376_256 15_707 28_786 21_546 3_806_204

Stable structures

binary_size generate 50k max mem batch_get 50 batch_put 50 batch_remove 50 upgrade
btreemap_rs 557_023 76_361_524 2_555_904 62_848 95_113 84_043 139_591_425
btreemap_stable_rs 559_365 4_564_070_850 2_031_616 2_709_640 5_031_620 8_581_107 729_344
heap_rs 541_957 7_049_481 2_293_760 48_382 21_512 48_107 33_629_605
heap_stable_rs 522_462 277_865_060 458_752 2_405_446 242_822 2_387_309 729_349
vec_rs 539_845 3_077_152 2_293_760 15_707 16_636 15_934 31_301_799
vec_stable_rs 522_579 63_342_328 458_752 64_869 78_799 84_161 729_343

Environment

  • dfx 0.24.0
  • Motoko compiler 0.13.0 (source dq4zmqc9-34xf70ip-6lrc3v7p-z1m6aq95)
  • rustc 1.76.0 (07dca489a 2024-02-04)
  • ic-repl 0.7.5
  • ic-wasm 0.7.0

Cryptographic libraries

Measure different cryptographic libraries written in both Motoko and Rust.

  • SHA-2 benchmarks
    • SHA-256/SHA-512. Compute the hash of a 1M Wasm binary.
    • account_id. Compute the ledger account id from principal, based on SHA-224.
    • neuron_id. Compute the NNS neuron id from principal, based on SHA-256.
  • Certified map. Merkle Tree for storing key-value pairs and generate witness according to the IC Interface Specification.
    • generate 10k. Insert 10k 7-character word as both key and value into the certified map.
    • max mem. For Motoko, it reports rts_max_heap_size after generate call; For Rust, it reports the Wasm's memory page * 32Kb.
    • inc. Increment a counter and insert the counter value into the map.
    • witness. Generate the root hash and a witness for the counter.
    • upgrade. Upgrade the canister with the same Wasm. In Motoko, we use stable variable. In Rust, we convert the tree to a vector before serialization.

SHA-2

binary_size SHA-256 SHA-512 account_id neuron_id
Motoko 199_291 282_867_522 262_958_038 34_374 25_343
Rust 541_269 82_781_773 56_787_252 41_000 39_898

Certified map

binary_size generate 10k max mem inc witness upgrade
Motoko 248_064 365_594_405 342_396 397_632 267_766 22_437_392
Rust 581_748 490_093_124 1_310_720 661_017 219_694 451_141_325

Environment

  • dfx 0.24.0
  • Motoko compiler 0.13.0 (source dq4zmqc9-34xf70ip-6lrc3v7p-z1m6aq95)
  • rustc 1.76.0 (07dca489a 2024-02-04)
  • ic-repl 0.7.5
  • ic-wasm 0.7.0

Sample Dapps

Measure the performance of some typical dapps:

  • Basic DAO,
    with heartbeat disabled to make profiling easier. We have a separate benchmark to measure heartbeat performance.
  • DIP721 NFT

Note

  • The cost difference is mainly due to the Candid serialization cost.
  • Motoko statically compiles/specializes the serialization code for each method, whereas in Rust, we use serde to dynamically deserialize data based on data on the wire.
  • We could improve the performance on the Rust side by using parser combinators. But it is a challenge to maintain the ergonomics provided by serde.
  • For real-world applications, we tend to send small data for each endpoint, which makes the Candid overhead in Rust tolerable.

Basic DAO

binary_size init transfer_token submit_proposal vote_proposal upgrade
Motoko 278_758 513_173 23_357 19_191 20_401 161_785
Rust 856_658 505_502 88_807 116_797 111_945 1_478_640

DIP721 NFT

binary_size init mint_token transfer_token upgrade
Motoko 224_935 482_026 31_119 8_891 91_908
Rust 881_139 203_263 301_918 70_807 1_624_865

Environment

  • dfx 0.24.0
  • Motoko compiler 0.13.0 (source dq4zmqc9-34xf70ip-6lrc3v7p-z1m6aq95)
  • rustc 1.76.0 (07dca489a 2024-02-04)
  • ic-repl 0.7.5
  • ic-wasm 0.7.0

Heartbeat / Timer

Measure the cost of empty heartbeat and timer job.

  • setTimer measures both the setTimer(0) method and the execution of empty job.
  • It is not easy to reliably capture the above events in one flamegraph, as the implementation detail
    of the replica can affect how we measure this. Typically, a correct flamegraph contains both setTimer and canister_global_timer function. If it's not there, we may need to adjust the script.

Heartbeat

binary_size heartbeat
Motoko 142_267 27_506
Rust 23_866 1_112

Timer

binary_size setTimer cancelTimer
Motoko 150_098 56_189 4_702
Rust 504_144 63_372 11_676

Environment

  • dfx 0.24.0
  • Motoko compiler 0.13.0 (source dq4zmqc9-34xf70ip-6lrc3v7p-z1m6aq95)
  • rustc 1.76.0 (07dca489a 2024-02-04)
  • ic-repl 0.7.5
  • ic-wasm 0.7.0

Motoko Specific Benchmarks

Measure various features only available in Motoko.

  • Garbage Collection. Measure Motoko garbage collection cost using the Triemap benchmark. The max mem column reports rts_max_heap_size after generate call. The cycle cost numbers reported here are garbage collection cost only. Some flamegraphs are truncated due to the 2M log size limit. The dfx/ic-wasm optimizer is disabled for the garbage collection test cases due to how the optimizer affects function names, making profiling trickier.

    • default. Compile with the default GC option. With the current GC scheduler, generate will trigger the copying GC. The rest of the methods will not trigger GC.
    • copying. Compile with --force-gc --copying-gc.
    • compacting. Compile with --force-gc --compacting-gc.
    • generational. Compile with --force-gc --generational-gc.
    • incremental. Compile with --force-gc --incremental-gc.
  • Actor class. Measure the cost of spawning actor class, using the Actor classes example.

Garbage Collection

generate 700k max mem batch_get 50 batch_put 50 batch_remove 50
default 1_074_136_336 47_793_792 119 119 119
copying 1_074_136_218 47_793_792 1_073_873_789 1_073_954_095 1_073_875_311
compacting 1_554_238_605 47_793_792 1_200_791_965 1_424_078_246 1_447_969_756
generational 2_326_734_591 47_802_256 899_105_682 1_214_812 1_107_099
incremental 29_505_471 976_097_724 469_026_873 496_491_319 1_282_778_770

Actor class

binary size put new bucket put existing bucket get
Map 421_098 757_731 16_360 16_930

Environment

  • dfx 0.24.0
  • Motoko compiler 0.13.0 (source dq4zmqc9-34xf70ip-6lrc3v7p-z1m6aq95)
  • rustc 1.76.0 (07dca489a 2024-02-04)
  • ic-repl 0.7.5
  • ic-wasm 0.7.0

Publisher & Subscriber

Measure the cost of inter-canister calls from the Publisher & Subscriber example.

pub_binary_size sub_binary_size subscribe_caller subscribe_callee publish_caller publish_callee
Motoko 165_839 150_138 32_873 12_214 27_075 6_629
Rust 539_139 576_928 57_754 37_782 71_207 42_396

Environment

  • dfx 0.24.0
  • Motoko compiler 0.13.0 (source dq4zmqc9-34xf70ip-6lrc3v7p-z1m6aq95)
  • rustc 1.76.0 (07dca489a 2024-02-04)
  • ic-repl 0.7.5
  • ic-wasm 0.7.0

@chenyan-dfinity chenyan-dfinity deleted the bump-moc branch October 4, 2024 04:34
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.

1 participant