From b4aae80ef7b83a50e212f00a852f8dfba9756dfd Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 21 Sep 2023 15:12:06 +0200 Subject: [PATCH] Update benches, README.md --- README.md | 69 +++++++++---- benches/bench.rs | 158 ----------------------------- benches/bench/data.rs | 12 +++ benches/bench/gen_data.py | 25 +++++ benches/bench/main.rs | 202 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 287 insertions(+), 179 deletions(-) delete mode 100644 benches/bench.rs create mode 100644 benches/bench/data.rs create mode 100755 benches/bench/gen_data.py create mode 100644 benches/bench/main.rs diff --git a/README.md b/README.md index 45d4d68..252bc23 100644 --- a/README.md +++ b/README.md @@ -19,30 +19,57 @@ _Version requirement: rustc 1.64+_ ## Performance -This crate is ~10 times faster than [`hex`] in encoding, and 30+ times faster -than `libstd` in formatting. +This crate is 5 to 20 times faster than [`hex`] in encoding and decoding, and +30+ times faster than `libstd` in formatting. -You can run the following benchmarks with `cargo bench` on a nightly compiler. +You can run the following benchmarks with `cargo bench --features std` on a +nightly compiler. ```log -test decode::const_hex::bench1_32 ... bench: 12 ns/iter (+/- 0) -test decode::const_hex::bench2_128 ... bench: 43 ns/iter (+/- 0) -test decode::const_hex::bench3_4096 ... bench: 1,349 ns/iter (+/- 24) -test decode::hex::bench1_32 ... bench: 50 ns/iter (+/- 1) -test decode::hex::bench2_128 ... bench: 233 ns/iter (+/- 16) -test decode::hex::bench3_4096 ... bench: 7,323 ns/iter (+/- 85) -test encode::const_hex::bench1_32 ... bench: 1 ns/iter (+/- 0) -test encode::const_hex::bench2_128 ... bench: 4 ns/iter (+/- 0) -test encode::const_hex::bench3_4096 ... bench: 138 ns/iter (+/- 0) -test encode::hex::bench1_32 ... bench: 13 ns/iter (+/- 0) -test encode::hex::bench2_128 ... bench: 51 ns/iter (+/- 4) -test encode::hex::bench3_4096 ... bench: 1,593 ns/iter (+/- 13) -test format::const_hex::bench1_32 ... bench: 11 ns/iter (+/- 0) -test format::const_hex::bench2_128 ... bench: 14 ns/iter (+/- 0) -test format::const_hex::bench3_4096 ... bench: 312 ns/iter (+/- 2) -test format::std::bench1_32 ... bench: 462 ns/iter (+/- 1) -test format::std::bench2_128 ... bench: 1,929 ns/iter (+/- 4) -test format::std::bench3_4096 ... bench: 62,233 ns/iter (+/- 523) +test decode::const_hex::bench1_32 ... bench: 23 ns/iter (+/- 1) +test decode::const_hex::bench2_256 ... bench: 98 ns/iter (+/- 4) +test decode::const_hex::bench3_2048 ... bench: 550 ns/iter (+/- 117) +test decode::const_hex::bench4_16384 ... bench: 4,104 ns/iter (+/- 35) +test decode::hex::bench1_32 ... bench: 104 ns/iter (+/- 6) +test decode::hex::bench2_256 ... bench: 828 ns/iter (+/- 14) +test decode::hex::bench3_2048 ... bench: 6,229 ns/iter (+/- 113) +test decode::hex::bench4_16384 ... bench: 70,582 ns/iter (+/- 1,774) + +test decode_to_slice::const_hex::bench1_32 ... bench: 12 ns/iter (+/- 1) +test decode_to_slice::const_hex::bench2_256 ... bench: 89 ns/iter (+/- 0) +test decode_to_slice::const_hex::bench3_2048 ... bench: 678 ns/iter (+/- 15) +test decode_to_slice::const_hex::bench4_16384 ... bench: 5,348 ns/iter (+/- 20) +test decode_to_slice::hex::bench1_32 ... bench: 57 ns/iter (+/- 0) +test decode_to_slice::hex::bench2_256 ... bench: 515 ns/iter (+/- 43) +test decode_to_slice::hex::bench3_2048 ... bench: 4,021 ns/iter (+/- 173) +test decode_to_slice::hex::bench4_16384 ... bench: 54,224 ns/iter (+/- 2,023) + +test encode::const_hex::bench1_32 ... bench: 12 ns/iter (+/- 0) +test encode::const_hex::bench2_256 ... bench: 25 ns/iter (+/- 1) +test encode::const_hex::bench3_2048 ... bench: 129 ns/iter (+/- 1) +test encode::const_hex::bench4_16384 ... bench: 854 ns/iter (+/- 8) +test encode::hex::bench1_32 ... bench: 134 ns/iter (+/- 1) +test encode::hex::bench2_256 ... bench: 925 ns/iter (+/- 5) +test encode::hex::bench3_2048 ... bench: 7,349 ns/iter (+/- 50) +test encode::hex::bench4_16384 ... bench: 58,211 ns/iter (+/- 2,474) + +test encode_to_slice::const_hex::bench1_32 ... bench: 1 ns/iter (+/- 0) +test encode_to_slice::const_hex::bench2_256 ... bench: 8 ns/iter (+/- 0) +test encode_to_slice::const_hex::bench3_2048 ... bench: 70 ns/iter (+/- 0) +test encode_to_slice::const_hex::bench4_16384 ... bench: 586 ns/iter (+/- 10) +test encode_to_slice::hex::bench1_32 ... bench: 14 ns/iter (+/- 0) +test encode_to_slice::hex::bench2_256 ... bench: 130 ns/iter (+/- 3) +test encode_to_slice::hex::bench3_2048 ... bench: 794 ns/iter (+/- 1) +test encode_to_slice::hex::bench4_16384 ... bench: 6,401 ns/iter (+/- 9) + +test format::const_hex::bench1_32 ... bench: 11 ns/iter (+/- 0) +test format::const_hex::bench2_256 ... bench: 27 ns/iter (+/- 0) +test format::const_hex::bench3_2048 ... bench: 173 ns/iter (+/- 0) +test format::const_hex::bench4_16384 ... bench: 1,409 ns/iter (+/- 7) +test format::std::bench1_32 ... bench: 510 ns/iter (+/- 5) +test format::std::bench2_256 ... bench: 3,836 ns/iter (+/- 347) +test format::std::bench3_2048 ... bench: 30,298 ns/iter (+/- 253) +test format::std::bench4_16384 ... bench: 247,471 ns/iter (+/- 7,873) ``` ## Acknowledgements diff --git a/benches/bench.rs b/benches/bench.rs deleted file mode 100644 index 1d682ab..0000000 --- a/benches/bench.rs +++ /dev/null @@ -1,158 +0,0 @@ -#![feature(test)] - -extern crate test; - -use std::fmt; -use std::io::Write; -use test::{black_box, Bencher}; - -struct HexBufferFormat(&'static [u8; N]); -impl fmt::Display for HexBufferFormat { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut buffer = const_hex::Buffer::::new(); - f.write_str(buffer.format(self.0)) - } -} - -struct StdFormat(&'static [u8; N]); -impl fmt::Display for StdFormat { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - for &byte in self.0 { - write!(f, "{byte:02x}")?; - } - Ok(()) - } -} - -macro_rules! benches { - ($($name:ident($enc:expr, $dec:expr))*) => { - mod decode { - use super::*; - - mod const_hex { - use super::*; - - $( - #[bench] - fn $name(b: &mut Bencher) { - let buf = &mut [0; $dec.len() / 2]; - - b.iter(|| { - let res = ::const_hex::decode_to_slice(black_box($dec), black_box(buf)); - black_box(res.unwrap()); - }); - } - )* - } - - mod hex { - use super::*; - - $( - #[bench] - fn $name(b: &mut Bencher) { - let buf = &mut [0; $dec.len() / 2]; - - b.iter(|| { - let res = ::hex::decode_to_slice(black_box($dec), black_box(buf)); - black_box(res.unwrap()); - }); - } - )* - } - } - - mod encode { - use super::*; - - mod const_hex { - use super::*; - - $( - #[bench] - fn $name(b: &mut Bencher) { - let buf = &mut [0; $enc.len() * 2]; - - b.iter(|| { - let res = ::const_hex::encode_to_slice(black_box($enc), black_box(buf)); - black_box(res.unwrap()); - }); - } - )* - } - - mod hex { - use super::*; - - $( - #[bench] - fn $name(b: &mut Bencher) { - let buf = &mut [0; $enc.len() * 2]; - - b.iter(|| { - let res = ::hex::encode_to_slice(black_box($enc), black_box(buf)); - black_box(res.unwrap()); - }); - } - )* - } - } - - mod format { - use super::*; - - mod const_hex { - use super::*; - - $( - #[bench] - fn $name(b: &mut Bencher) { - let mut buf = Vec::with_capacity($enc.len() * 2); - - b.iter(|| { - buf.clear(); - write!(&mut buf, "{}", HexBufferFormat(black_box($enc))).unwrap(); - black_box(&buf); - }); - } - )* - } - - mod std { - use super::*; - - $( - #[bench] - fn $name(b: &mut Bencher) { - let mut buf = Vec::with_capacity($enc.len() * 2); - - b.iter(|| { - buf.clear(); - write!(&mut buf, "{}", StdFormat(black_box($enc))).unwrap(); - black_box(&buf); - }); - } - )* - } - } - } -} - -benches! { - bench1_32(bytes::ENC_32, bytes::DEC_32) - bench2_128(bytes::ENC_128, bytes::DEC_128) - bench3_4096(bytes::ENC_4096, bytes::DEC_4096) -} - -#[rustfmt::skip] -mod bytes { - use hex_literal::hex; - - pub const ENC_32: &[u8; 32] = &hex!("c6ddb328c7e0eb6ce7204daa79b0ae25f632272b8d4c5726c2cbe64cf890cbfa"); - pub const ENC_128: &[u8; 128] = &hex!("c1c19d4a28434a8b65272ecf74c4eb0ad8a5106639d54cf417f7423bfecde55e83fef26659ff12f3bd9f19196d6e5f84a4f8a95a3bf3dee61886e25be1ead60864d8722c04288521b153d1bae477a49e000932c83e336830d41d86fb825bfc63e983e54e007532f1c4cd40c7cf346d0f736e03fd20fc65eaabce46f2fe29d550"); - pub const ENC_4096: &[u8; 4096] = &hex!("7ab9bc64153fc2d93d09223d9db09f92522cd1904ef4d798855f200245a18e7428e62be563c9f8c1043078b222388c3cf7deb12297867b2c4e3e751f5ca1107f1d317a85bb6fd6891c2ffb5b1d68b431e50010b7aeb26a39a417fe4c583c68f1a0133610f9f3d440d3be50756504b97bc0af8c01d3c751792d6a549ac4b4cd3b250a3fdb94e512dd8825c21f99b274a39118ae60b200a0ad8f536d268b2c83eaf8c7da21ee430d1335ef0932960bb28954edda29dd8f0be40b5e77c714fb941abb9190fd3bc020b52b2411cc67487071081f34bec7177b944cf47587325e116850a175dcc713a0f01738d2a625e8aad3b0b656d264e40677e6f390b9da8b458db018cda521b4d1c760652fc052f9a8645e144d9407fd3b2cae5f64a8f66261bb344d0dd1a577133a06aec6d0db9b5df3327f4e2a62bf84474c100cb0d4fe33f7f94e970692c3fefdc7f1f0b1ad1c50b729337a2c2dd41f40fde080f60a87c77aae77aab7014b2fb557817998a55913be1b80d8d8c493a0f0367d00732248ab19fc8f159577691624a4280be729d91dc7daf05a6b1a20cbcb3d7c30eb38fdb6b823f2a3a95f907834390608f7fbd4fe399ef03f8121e8a716594fac89752c6878621db5efe829e43a2b882dee0543457deba13380bd4df193d39d88aceb6193f82138a55b036533230db718801da6d9a87b9007f2721f46e6e105a0ec111fb3224109b3ca5c3f29da35b93b28d6911aaafe55e16c7f208ee5a8333a726b40b568d2b4ea4125d7445e6178721988904a8c814d63e5c743eaace60a242f836c3464681c41a370b8453b909031b3caeb241d9641b89a1d170887463c74d19d74b8f6126d1851caf7cba457e571bc29a22944f696377cd30d8400417941aa012a9323c5da8efd7d1ed5074ae5564424f55d50491b61aa7ecd913ffd3523168da2b18f2a2d5a1e5349dbc85edfd9fefec0af4ad90a502eb24c04d3b363b1a2310fb6b4dd3a2a0f78b6e92cccd2526b67604eaffda6a1f7a773069243e04ad3c2132d90f0b69ddab778386479154031739b7b08ccad3ff6c2c9b6f6f11f00edd750ba5a6fbbddec5899fd2cbb5b2963f23fc90d956621dd2a1756803ff6eb6ab9380b009420623e73519b4743baae3d1e8d5ebe622ed3c4ce145445892a75e46691a2cbdfcdbbc23538e9c8863ae410cd7b3e7e00f5266cb0c1c1bcb760008337b89b324fb9749125bd691a3c8f6b79a97899b9592da770d597a91979dc04b6c8fd696b1b2b204c9906edf3efbe2c99d2b8d2f14968f1967631bfb590b753522fe5040ec563a45ff56f05032c216e3346a5b2bc4a753ddf6737bc347432036f36607012828d7881e1314c65b51d4866694afb003bbdd3a29f99be92d186b8b974e5a12e294e9c77960c381cffde5843ca2eb839659ef509c4b56e23126ca958bf02efb0feead97eabfcd4862265a20bb2458181856e1bd9a112f205ffc0ca8faea7a0a819eb0dc43038565db8fa932d849db50e1b76f966c6e45c2ee921f370c02b089195fe1103c50198ab5247e256ccbab0969397449e4b53b41e28ee73dee7be4fb02a5863b6f589c69b5f52ab4a8f1d9620059b8b833f35251049ae8a49efc3c163b7149396cfd2a276f2b365aa110de50fcda299fbb9364c7ee21846097aa6bf5bf7fbda7ae83adfa2804871f100179157573ed5ff81b0e49449b0eaee6486399a7cbdeb40ec41cb2b2e6ef249d003cca022c98056ad34e235ff307e3eb213c7319824d923fb3721ed38689ab6d464da99c6dae31aec3fa3f3df03fb668aca2993f25a1e4a12430c85196e4de55b469faf80961378e4e385181cfbc6581fbcd745b9b4bf1c734d831afff53b9e304acd4a6e61bbb48a44ffa7a5ece73ebe64415e59c27cef3b6718b768d0236af06cc3b38e116ad8f91fbd71a2a61f4e0cd622251138dc385984232ca19eca41af07db5fc1f87eafb8d60c853fbdd32b8d32cf574db31c2c46b4566b1646ee1f79c6a352e2bcfdb2f04189ca857773ad6f1b2f62652f3f367fad2cdf75f360af06056370d609b587beed6d5e8e59cd77fa54ee96203a65d9d1d96a056df2834c314569a165c08cefc7e047106f3fd11e5025be9ccb2aad4958e59ce534a3e0f1f772b4b5d873414dfa07e05e3b665fcb93cd52210c1d80a47320ecf1be0cb2cc0e739139747e8d8464d01b50ddb792c68b658a2972cf3070dc2167fb6b11969e52cea707f7454cdacd5b05467d598a2d8e4dc6532e9cc399cc70292ef63fc2749230c832b5d3695ba5584489d166fdd295b8602151eb94009c6b41e0640e44d776614c0876d8df580c49abaa71e8881b5b7de5ca6acba334f419ef4232e948109dee19e4e3a3fbb6c3bf9cfc02d11f5acdaf2ebc68b528df7c71a07bd60a68b20b027369d0696d5a02b09bbb3db7bee0b00ed11486cedb51680f792dec2483fb95d607920b15c17769706050782c30fe9dbaee0ad7ccf2cc467eab008d46d6ec9525d98a238fd1a4390add976953d4c4bb4e0c5a08779f38e5bdab2f937a72ad864ff6bee9655dfa59d5ac3e90e0e3bee7fcabb6dbb95d510e11df1c48a8ba9b00af841e7487d3840e4b517559dd63dc91c2a947adc87090f77b4ca40acc884c54d3451349ce946db298b2ab1d76448dcbf7fbddfd6437d780be294179f327bdc64f7f1a4274b1e1d986e92a0f1495c3fed33967dd5626c03f34e47bf280f3ce4c880b7845d2894922e0490e75f3704735d1f4e4f7e495883e7c2ac7cc00659fc1d543a923d913c23d69514f20c0b7fc42d02ee0ca4d133f360e145ecd644f3d1e38702b0d52ee4a0e23ca7f162168bd26c3231d0ed09611e9028253fb6fa9c1ce5024b936926d9295c55c245373489d318e8d3b7bdae1903a52c22b798e69851e224cea1e16463c862036c7e2dcf767894caee2713f5f0864dead7c701c92e9f7cde906ff30ff222dfaad894a6be69d438c5a6db13b726a1b7bd56d2163be4b53383f9079194d209a585a36cc7d6513e3f6de7219ca24898db46ffbbb7b03368cb352c50ca47eddac3e90915c24e0cc70220d8f964d3fa6bad83bea976bc125b77490db1a61e4f29f6c656febd24c39ceccedc4d371332c8222597eb0725f75c610bc804bee63a67890c3fa3571e066d75958247a91af2e48fa5337639d317880af53d951583025c170d09bca0721096b95007507ba0f3203c589f6eb813be2b3ec300643c0bd51c1d048a1eabe3784d68e5a6f9db5b623354e1f7ae69604f4d9003330c09c860763169a9c3339d173434c879fcd07343b7c31460cdca5a223e41f12b6a7caa145131610260130f54446a350afcacd0cb441f2d4c42ec1928f53f19ed3337ac3c18949519fb11debd7779a7c76467fab34d929297bbe61f7686f8670a7f0f88fcb88296d251356c5d8f4f3f5a07c4c9530e04b43f0fda14c10d508574a3bf3ccf1baed4f0b6996b972fe44dd437977a472d62ca68aa98ddd69feea9a25e379e2de63014bb230b70d88785cef3906bd263634a161233ca220e0d7af4336e5fe414aadcb0a366083584f47e442911228d794f7b03362fe0e07b42ab08e7d1f2f3965e2ef1854c6689f8935d6d09188f9fb720bc2effb6e3aa316807c57b76e51629b926590fd9d317715b05c60df51f667a7dcfca6493187cb50ab1a5fffc175b133a14f91ff2320a7f7683485367dd897030bb8278f442ab79470a65b4e5adaee72175702fb0fb5c1e70faa937301a1ee0955961b9d843b14887f3bb6f5bf9ae809ccdc5f61b9e0aa4bdae7612d461964625ddf2b314b909becf3b4dc81467aed657c65ccaf961c2bee176f20fcf44385c030bebd8ffaed3bf6ce14fd3aa9beb549da955147fbe37e191f975961bf234c583ad2b0ccd9f81b2b1fd00fd5fa1d51e7e497ac1a469393bbc58b82af2f9beec41fd4d2f498dcae448f1f6f402d7c85b1f46bef33622da4fc2c72109f564a1393beabb52cb9bb18e7ece3d00a982fa2dbe41c3b1c3204dc1e1e2dc880824cdeea858f996f06a0c6f3b6a33fff4a44db2707a3ff4b0ee63bde964f0f1d869c37d1cf6fec3399a187f1272e6cf4a214dc34cc914d58fb9ac38b60356d4c73807650c34a23ea763c7018f7c0b22782f7fd842c475bb385257229a03bff09bd7a1c69b70a6fd5ef4460ddd43dbd63b6dfcac00591dafd7657ba0cfbefc193bb4361bfd2a847173c54feb7f25f93678e27167b7beb84eaa8e70da714ab83ea75f018e43c649e3efa2c867597becdb73352cae6e10f6cfe3c621ede7d2cedac145479ccf5f0176ddf221701f1ec51dc40772df0991d3c2f89c28669bca9736f00cb39015f74987b09599b1cf0963d587ba1bea9f68ca3ddab3ee03d0cc1e5dd13b1d1cb01641d610c88212500ce76ba313ac360952f56de1c4053dbe9a1b9d7258c4063d12363daf547f920a259d1e8177e46ed8d98f940977ad6f8cf1373f4f27718f8de815e3cc35078f393f968844fb677f2c16ad824d9f15dc0ef91de5a161cf7b686cc919512e9653236145b00167adcf60f25ff2e04ba6d5f2e59c2bf3dbd27b248ea0d82558b852caf900bf638a0a1703247a39538755e2daabf76d0ac47415eb7707b8400e2990d1542497233f989630613f106d7a722098bdf51ac2775a09c5789d16db42f8a7203969ab1551dfa3738215e4df23812716305ac40f69c236664bdcc6f19e028bae4d68a2c7d587b5a4f8b555568d77c61bbf794924ce18ec34c08f46fa17363350bf48a9880d934f5628436f7ef779750a7f54600a31515145155eb4e19338554bfd6256f53526ddf8f07e6d1a5c20d3a55fa603bd6e4781e54653270b8f377b75ce6260ff5153b0f20b7197972a4a320d3787e3d795353782c4c299bfd2dcbced2e5dd1b98ca72f87671e9a06689eba9ab58a13bb2fb856a579a654f74377d868c14c4d32c436759da19167e227c85017a8ba3734fcc7467e59597ee65b344e446abf9e2e6321da203829c40d4ed6da5de56b7b374125ffb07f45820b9d378c434c218455df145520bf51ec2dc3adde3d69cbb5e25b42a400b833d564bbaebd728500fc68aa6d7a84a727c258386c40d2dd0284643b8090a819cb0de4c5f8f702d1db64082cdb2c2c892c584667d90f4af35a22ebc34d811c55e7c61a1e05f47bd672d33049e0bc7500920897cd6f9928e9a54676541ca5d4620f4f7c7aed444b84d1977d36ef97e0e5dc556da4900e2998d3a924cd183ab901860df078c047492b7c284e49d95058d87c9434385b49f8032d47acd69b9168b9c45c228e6af7c7b79b86af67fd03f9b1ca279ae2e94056f7399f4f437733d70bc3b6d8317d1b0397341a204010b2396fc76b786d2bb2e19985039f020b9aa12206aefb1943fae16a485d6f9854e6792be2f9d1bc901d98b59edf9b80f7b8a682f8e0e93e87929d7285ec8442f1d3e5b6158efb338d4b330195238e645d3276496241cec27056a205b59d4f1edc2d505ab69b506d49634e637e4634707f66500dc576895ed12118c6cd22ecac150aae81ae827b06cde0913b4d79c306848736ffb0f85d60f4f8acfeec16e7c17af748b93dc6eff08a77672ddc21fddcd729cd84eb416c7003f15a30ab0b756a03cc0674f9c7818eb1c197d81af566751473a3f2780356039057a834a35aed5fbe1a0ad483600721184aa4b26abd1a98413387c28b13cee1bb141d957221e9ff428b1ef262038b24bee5636760af8a1a1e2a3cc3bcbf44861abecf45f36f4a4d02fe84314016752fd7335fbd8f6d0"); - - pub const DEC_32: &str = "17fcf46621eb6d2aefa3edb5cfe90e2f"; - pub const DEC_128: &str = "fa5943385153d8d7383f5514d5af03a811ef6c50e143362f42604e6cee015694fef5b57457c48e2120b706960f1aa8ca8b2b689367e383060403f2c75322bf92"; - pub const DEC_4096: &str = "50fe36085e0358265f268b8a346dcf1ad21af411014847ee7acdbb514d481547ced9588d7340340f53ed238e81ed95d7222f31b5240716714ed14ad242a339ba384ac55abe04a2a7fe29dad466d6295abe8a2721ae631daaf8c252d3018583087b0dc04b751e8674cb3327ded952dbe4de5efda1a024612ad39d5c2cbb42c4dbc14a60253d198574348f2c9cd86fbb85dfd47f2a065645d0e5fb50465573676aa51b4c9f3fefbee1c26914692423529ffcd12cb005c9cf11e2d4d8531a80643cc9a7f750af11e382c3b91a20ff6fa115d90fd2fb6f9c02e1589abb6f58d128b58f46292879dd9d3464d1bc54f3fff4a51662f8dca64fc6c93f5e7c6093a4a4bbf7e6b663ee4b8dce74bcde64071372b6464e485f5b84d078b64ba01735b00fe3ea777494c95d04934b9cef30c08c5f1b4d22df4fd4395089c8056dc0cec9600d4647a6aa738065d2466e23a616e5d0dae28ea8635ebf992a6dda3452a11ba96744737a1f1f663f4c3fcca70206fd461a005da15702b69520af0e7a0f2e259b6ac7165fd31eeb18750c8fce982bbb2bd80adaffdea327cc59c2557f9ebb0c833bfffc5d0fec32b927f42d859d338c83451667d7c090c5bd40cf60ccf11c2ecde16ae7e64755826a8dfa9ca074e1e4951357cc2c881736a37ff2b429cea6601e85e5129dbd1a889e68fac59293ac3a200f455f78f3323577750c7dfee9b5de34401ec67bb0274caf72e192fc6bbd8802d5737d2f9d80b8c9a0b1f284ffcc3e0806dcd4bf2943f2e60e15afe12247f2952d46e40e3597f3bd252696c906e29ddbcefe14893bb6959e5a7e7b0e74c53cfd1480d0201a99f44b55c561434216dfb4e1541850258d102f71ee768e57a49f55a6de94df9dd3f712a17daa61b5cc2bb8daf50968168ff374b9923f9d668046a974b0d21b316e217256c744e1b5fdb245a885d7d1eddd4c892fca11d48cf2353d3ca6111faa52eefea861c4be4e348ed33a3694f8039a27679e2d2d279e79ec8d755b5543768c96325883f12ecedf32e078fb1ea016ffdf92fec58d41a81d458f8eee0848f11b0ab94cf61a220c8916b5ecbd23e8a2a8f8ebe5218ec7d66a0a9ec9bab6b00cc86f3930fab52e54454f97df355870592c3ae074281e0b81ec103aea2b879aa4f61ab606c8fe5f21c841b1d3eb67b72f7589023c537a9027c12f50f83d827f45693338ad233347cf2f6fb90180fadf0f718186615cdefe044a777bf454c9f025bf26726acdab1fadc6112ca9f10db89381bb0c75d38e5960897cf2e71093fb5d86341362fdbb51c2f9608c067118983d3064266b65593142b0f545e47f441658fac423d1d9474713f581f1e6f033a3c8ce4dbdc5d25d5435117d8ede16073c068aa1bd019bcec8b1952750fcdeaf797a07932025704a5f42a796ad6e578b5dbf1ad1e6be02bd6a3683c077e27cdb2da4e5ed3caefbd08b1539d96a4ae77246e134300becdfc9a7c970a9aafa585a2e1a934fec89e2b17620b23aa581ef9b7096bfde51e227db23b97541333f219e634fe869705236cba9db31038ddaa5a632fd43f4457f620f4eb8c2d24dfa694515dd287105465ba9fc0e09d51730cc5c7c55dc3863673ebf0dd8b4b90e9d5b60b5ea9513b1f9f6383f128a6b5dc84e548cffe981e878c28e9501bcf653ab0b114728307e1e9ae50a7b0e91df1140da66adb31283bb91b211b9fcbd42bd34d211e2fdb897320fa0a5c6b15937562387fca383d7da966e8f94117e0c1eff6f5e51702b3ea2913f2029d0190407807a5b23bd0b3da1c2c64a4df740b58ada9d394d08a51455ead6f826a3bffe9250c2df2ce659d02844d6e521ff5d754550a7f704ce6995a0a96aad536b7e0e43568d441406d2e2b9feeece6182be111a12d7b64247b09a8837af4695bcb7cec85606f3c400ce2c6dc1d9e6429c0ca9ed8d40886da060ecea75a83efff2794ac01565778ab4cf076915f597524522f3c45f6ea0db4c83f364fd44062b52a51ac70743bd071dbdec3a63482951d07ffcb5ef8b83aacbfe5cbda2f7f241bcf0acc0804a3d5e9e65836e2bf1986ae13dbb361954ec0a36733ee659136767b779451df5684e90adff55440960b9a6602df4c6084e011c976c25d33cccab6763f230e1df8e5b0c41c6a1dbadca5f88785c931f8d9a1283f2690f6dfef5d20fcca2edd3c599d1f64cdbe815bc7e12ae700db9c928ad401b6aeb2a2ddccd1e921513e2950cd35a220ff64d201e9b52416c2a4b6881e8563cdb94dbf132786303d6d1f0a9f04d4e56c12201e45f6371f94431c7bb3111ece2154834b5640270eefb688f3751c4b98564fd71ba3c07806afe6dfe6e64e1c26cc7c1a8b437a829ac690a6f13603d622e6f3241e5592852ba7b1b544a3429d972e1470e449f1e7337cf3a672991b1c59b804164f2de4074608e69f53e6c6db01715e5f642c93c253a8545e8b70946443e60a934a2867d9ffc6ef0885a7c4756368f0dff8184e12c87a369a0d03e341e69ceac9555585df7b3a402ac06ed934678b0d882f1bb210feeaa6641503a9f76db8e25dcccc732161a010453ede57890bc1ef45b182c1423bdb18a186cb630d8c620d570a6638fd9c21764c2f0a1b5c2778cbd7d66e4f86c3b858659dbd67ec74d5ceaf9c4054cf21c419093647fb6636000d5ea0aa55d99a96f7d633a240db356c68fdbbeca90fc83f80d187e60f577c96d71c1eb951fed1e7f656927252e864cc2e736b711d033cd41ed8fb308a88564c9b7b34cc9d187a9a9e865573fb771a77df554037ca376bcce948b63aa1d38ab076bc0bf582ce8a42218d1fb3389f6d803b6c0623fce8a91f86146a6eb62023f21f22f4615d8f9daf7de826258122d84d92504973fbde421d0ca41fbc488"; -} diff --git a/benches/bench/data.rs b/benches/bench/data.rs new file mode 100644 index 0000000..5868baa --- /dev/null +++ b/benches/bench/data.rs @@ -0,0 +1,12 @@ +// @generated by benches/gen_data.py, do not modify manually +use hex_literal::hex; + +pub const ENC_32: &[u8; 32] = &hex!("351f3e2a03861a9c7074ba61c89c0fca9abb32efbeb98d0dab35bb05c63a92ce"); +pub const ENC_256: &[u8; 256] = &hex!("4709c39e8f601f0d4bcecb57bb21985f605710715f0ab358a2df4831dc72ab247727493d77326cbeaf45aa87d681074f84ce256769cf019d2684fc87bbd071a6536d0d0f7eefa6e35883d3d123d289e95ea01bf6a6d8b8f40155f9f5bd35ed482b0868854365efb779680721cdb99693169a590d395bf9d6d503152a0746393a280ea4d13be608ce1f33cfce46230ee730b17170257c67163f1a992901f4ffde3c2d51b60f7352d67834de2550d35f8dfd58223807831ceeda0dee270df3f70b587e205b0856779d72f3389e5415217299eccb77b7da65d5a28102ada769346326dc55d5db8cfe59b0f83d77d9d6795b9deb4214ba1433313b8ed45539788729"); +pub const ENC_2048: &[u8; 2048] = &hex!("ac9f2c6a6afe1a422bf95f4ccfa36aa0e68a74b7e1eacd11b9690688a1157c51f96dca3e79ec936317eab31b47fd38b03720a28212aedd55fb73f0ff030925553d9e799b3968065f24e482eb93935b3b3b0afd9e62f490fde1340da67ea319d3bf1f8aa543995cc54cea96515712bda055738d261185b29a5d508a9e011143e60413701fb739dac91af4b8a5bc95ffaca03a71a5a2f3a36a105388a6c106e8ad4b8378d89e54d633477c58d7ebd26af6a35f15e387f0a045199517a4643833e061def126586b664980cbbe60887f81df1e780c974c81673f3d49bc58ca54bab87391c5ba48fe2d2c21eb7da15afd512ea2ab0518a3935372ba8c169ddf3780dd8501453b2fdee3062da8faadcc6c318bb013768b410267f0bdec8b570eaf3d77f9300772b656fcb20e76165891e91cf12021eb3fb524f87733d1b992bcac6709fc51db2574ac9236b11cdf3a6a1b55056e0f0a118323f9c91b115774fbd81d288c5f0e5f670dc2809ecda7ec53555a0470870fe70d71186ae0a14dea1d471ab4ed5dadd522314741a175f6e1c70fdc4e7a76a5b69c210a9b7ea66fe7f141f550315b33a1b6f1224752b66a8ef51bc031cc4415c9ca0d0694b3f34ac655ca528ce0234335deee455b4f75ede09f923883526f6a9356c7fc2c66d189075cb7c65e5a02ff0036c4e2a6afaf8b9d374cffd8463dc8cf5c0288ef9992493cbc59ff2e065ce9bf617516790bc8fdc41851111e0798ebc0c345d86ab04f1b5f24d308ea6f4cf2eae00932fc48dc19a8a557bc5cb2b95385dfb79a08976ba373ba1fa80afa36ec1701129f64e2c27f58578020ee9a16da8f8be786804a09c74001ac830d784f857b116c5429707e2c7996d96504d8ff8d99394745c6db4cd6bff1dcb06096aae715e9813f6de68b675ef3122ffec5bcc31d81d21a996a016c1dc045484815578f425c885679323d9a7b993a4d02c544506be0174f1c56ac2febc6bcf6224684516ee4ca8c338033ff6205ec39e8ca5393b28557158c5199f12a601cfb9e2114ecba23374fb4af964647191905a0eb538283ae8ade2c86ec8d9834143b516e9e746b54f066ec5b6494e6c669ae77491897b9c5813eac1ebe46f5560d9466b134f5de07684688c4b05d22a9bc734c87678d9d3831f8307451b2991e7c19a61f26081a605f5ed24adab5b98b7db3d223c1db0a4b4fe85ce71a2ab15225d56843f632a29fa9143cd81f39d8beea7c26ce815824f5738b417babc0b0883d2056f685c109aad75b36f7bff1efb36b8f649ad6b9fee28e08e61f646ad4ec6ed884973bea0f268e79817cd52b5332b0f611850b1f8ff6fb28af3ebc3321c4446a9690d676b53a627c08c2a26c452d73a3b4e26e48df36973a33c1b03250fe42b0d670d98592ad8c998f213eb1e89bf31c4b0d6f88b595aaf7987d8fd5f2fe1703f5c692987a6245cfbf36af3e0b337b93b2aba548a14c15dd602a9055509c3d7e1c8d6f1e3fe37f16ad069fec2a6097efbcd925b8c907570cbca47031f1e0e6323a8156cac258d463d85b920d7b47a1e604d67d4afe4c4eaefd0e326f07d19e23f6eb7e992b98cc924bbb4f79b49af68a717b7f2cbe0e1f80f1f8e28c0c8f2dce0973ea7711628b0d25ca07ead81cc07659ac5c0adc4452b2df54280260dc675b87e2c7da8a6514cf5317a4d3d3892ecc45d5ff0a54f458b8efc1f999302d3f350e1ed5c53c6d70d2dcf64130e3511c577517bd192ba9e59dcad691751faae5c4cbf6da2ca2459e8d301ea6fa075366e9c524c6b89fa1c5731bc2c46735e3e96e8021322222be997a6c383fe24dc86d9b4b05829203d0c918b3bd65156fbc7b3592efa7dad253394f071a2db751ecef660df775f2c087ae02a7d42f1721c1c211aa03b3ec3e1bc8a24d559a7ec8e4dc7a79a9e12939e0e4185cb4f871e263a3476c2b3d8c3460b732b96e1353c8517febed7f31dd16d266a44ca8cf16f7ecef2c9404208583116f13f11c71eb372327f8b8ebd49f2083e3343201c7a6b611de0fda6a73c2ac83eead8a610e45a2f42f579931d582e815d7683c617d94896783f33c3f775b3a54e42bd29ec8cbd79bed25b2e010bda6b55c9908bb0010703dd10166bdec9bbe25a6cfe329dca0ef18ac1b43c23d49faefc561e7bf1e75e4edbd5810fca29d0e88ad043f65c99e1865772caded52b5e3cb79bd086dadfd1c97d29516c10838140600a19ddc59cd9c8604de2584edd366361d0fa1a97ee774c15e0f3dadc06b756bad3cd7d7d660228bf95735037013d752c41febf1e6d4a4d7564efb90ded9fe88fd820770bc93f30bbec6f57de637b168535a4ef5e3385918f1e17b4884bc45565d248b2f7c25e68128f6661a9e5daf16fa6d443af2fcc1e01afa9b8f59582bf4b28db64473d011f9f833beb07993ccea688056128cf3877cde71cbc4f03db4e81432690372c296c2eace95f07c70dc6782761cceffa2b780e4549f542354de5246f30762d13c8bee56e5a656b30ebd3630ea4ab5035704dff9f0e2e78f140e871b1985d089f5c11648703b75c348f736317209fc4371ece3a373274ddb9964b61f0c1ab10490f0d1f6d844686f319f782c6fbaeae49eea08ee26c39e11a0ccf424eb70042dd5b728023f80e2b4eff53ad0ffdcfb81e953c4d3383600cede174922f9a437a7565c9486b6fb957ccc341b72eee7d8be20b26e189f51d5193dec3dd8f5befa02dc71502f3e75c870287313353d8196cf9985506f02b08c3c5217c7897e58c970d86bbae752210c4668ed5af2f52153caf5b605378fcc6acaf402de72404569eef04cb1efd34d0f8fdcd94b30429bed10519ffa0ddcd8ab645d27cabae14f18b339a9fde3deec8db62c287871bf677901e4016cf6e116"); +pub const ENC_16384: &[u8; 16384] = &hex!("5487942962f38f9b92cdc1e452bc96ceec93d75ed1988363e74e4836bb8d6ffddd5688b861ff650d8b4a23b80846fa4162c71b731f24fbf7135aa5c43730b1ed5e499ef42d28bb4876923536192051ab4b00faf73b52d31914cde19090f47397ec6e67a31452cd7cebbd9fedef423d80fba10580fcf3d69bd135572ae9634893da9192eaa7f312e59536f794ab82734731a7e36453ecd4318aefca9351de3ddb6cabcc1d5142e1db403b506e28ea0d10daf8ef7fb5038be1673d8d330ce259463352d7a9600146df7eb19622466615d738cf3c2f8fb82f2721a5dabaf02624716732de3688e466b773db964050b22995a28539939d9ad18f21152e8d3b6dafe1a1e291071fc16c879da72fca83f7169b4974419ec50920901cca16dd2fa703f47f4f75a90ccde75e3baa509e1518c51bb32acf296a9c1abbba3da29bb4e8d1b72bd766ef73a7b0f5af61b4b3f72c155aac14703942a48c9f681e84c342670104a4d6341fa8ce21d7d1b0835111af33d634da7f67de0328c1074cc284a145cbf27fe6c6097f75f0b5a2976429cd734d25486b010a612be298d542919c0a96bc28cbd79605be8b03b291609bbbca1313d74738b99f4704cd4c7b6f632b17072352e2da9502c74daa1216b10bd3826c2ab5d2ede5b3f6931e18fdcfe01b6f43d81fe2ac9745f5ce25088bff99347697ed52224459a62ce1a953ff888f18738e45b9bafbc9e991aaf9f5c65315d78efbc547a471e09e5fc91e9836306003b413c29f2a58da07bb706432a05a1a339f368c9f00de0d7d7c50a5129ca0f0192eb2dbed306d82066a845acc064d6d5f2adc9eb5834b373871eb2c2c9ee1945b99bb4d16597846c37096a0854254bf4a9a7a2ebcab504240c7f30f0329d01b8c96c23512b3384dbc50c755c3e7835b15f41da1a505e8ff71c6f69eeeab256cfc756222c18764045327b7eb5b4bf3b09635fbdd693b62d8f5f6976b0f05acc00d7df54a64903c7282912a9277c1dd0b650e8a2dde6adcda9be7a73e7a20273c245469c1c663c0d65ad154997b968c60e4b789819dd81148d4646bfe535f0bee1fb4db0bf3fa271a53fe9e4dfad083154b4b55a78ce75c10f1fbed211434fc3cf2407a59b6fed117f49d54d4aa1d78f0b32593210e15d922bfdb9dd61bd945001b8d1f5680f2eebaa8a4cd3e474b3d6b7982e409d6f37c1eaa3aa97524dafe6720e48d287d7671ffb692d9b0cc6022a6fee684bfdf01d37248d42e03480bdfce402ed58954f13a1f17ff1071f963848edf66d63c6cdaf5da2a1e9e679528973d8773d7cd371759fc52546edb6d755bdad147a60a015cf0816842a3f8ad17bf21c319451299265984f9f050775c0a1b8f7a123b85df9dc5f18bc40a170ce7dab76d897c1005be5e24d30b1d70d8e07fd9ca461a070d1d96f185dbc8e2d3a254a9cbce894e5646b952921ee16756c947325f91b8e58ab9458f8fa20ca80f261b5b117aba2eefb6fb52f97c186ef8bb9c9f24da758d02a8d05354f3fc9925419b851fc2080e1381152486ae3d25167373ef4106b922653cd0a6ab3164c989186eb77ff58389b8d605a84b31ab946a14c5ac53aed56158a0945c39cad645a23824265ee896329ef055536d215946be0c8c31b13228eb6fa5a098356cc058064b498afea322cf9d8680a2c939e3591f8fad2a938f7966f6c8e7cd1bb093f50319e2b5f5df8163e738073dedf70af6cff0ecc801b3dae49547002415b070ba6bd8366df2302c9f14104c3a11ae09a05d52f69614a3236cce80ea6b4b7e8972b7d78f130ff23c2a688f4c68816945a5332ae0fb5bbd319955124ffa39efdf84fdf1075883df86eda0dc8cde16392b1e85abd4c5e864b6bad2625ed736d63fbb9d9a46fb7a9e0e151ad98512fcd7c6b72dd54dc1706a358523e3add6af58bf1a31fcda0c2e40e49ec88451dc2924e0ac8f1797954fd6a864ecfd18a795d62fe71bbe41ddf14d544a1470ce9018498f1dc9b8d9b279a611b6aa6b4ad8ddced7621f4ebc02ec2bd95374486e5687a67e1459886e415e39ae4ae60966cdba2de57a798172b2b0206fe3b99ea815a876df7eea583290eb4255f2243f89dc468c0d943cf1960e463af7829dcc92966b8654af80bc9298ed0f6e28bccb85ccf8e53afe854c732e91876efbc7c12e4f5646a14dd7eb6340dc51d08e82502d12c52249c5a3a734cd3b81380dbf256fb200d40e80a8ddf45d80e04b114708fe4f7e74e289405636decb36925528cffe37715dec6e38ba9ecd9deb952585a970364176c87729d4b993b0015338f760804cd5d747b55a4f73737fba4f0612196a44f167a1a73f7387bd04b639023cd6a0888c01836178624364a9c0758fedff112f4e20fc7116dc97a385b3da2b0b310574a228c141e4e23e3fcfd4837b9ce74d4e941f770453b8cfd6eea1d413824620c1a949ea61dce0ef0261f8340966efde45c84ffe3def07239a9125ca75ba4a1220421f566ce18370690c2f7214e0e3bef0a38709271ca45128187d7f15a40f661ed0cc93f127e2915c118f6ad327f862fe0b504b95965081b08e2adc3c2a69de1c13f3fc1bee5e6eb4952fdf72f11f9586b40bc61a0d966b0b7263afb369b72bfbccbfb8801382f00df98fc892f3bfff77ca8d32f1e7cc60e3bf5f384c1c7192d157c954ab18abe131d7bb911fa0cc4aa758ef372af1e7adcd7b358dc31b16aee8a274b6df0d3f4acc1a127dc4d090e92b6d41c77526c1e673d5b258761a27488d035e47060709648dc68ef84c130f84afe2e6f266b0309bc88f412de969b226fafe3c02074e8cc0dec01516ce0f3390bbd758947a891370fec4c325035cab8df2cf545eb612a60ddc3451bc96f70db8575b231467223601c4c3165a5bcb16d2f1f96e8f47e28349db194114ff96b2c4b1f14fe2c31d7141f7c3eca8ff8ca91f6ed5ace5405d056c8b2e3c423922005923fab70467cbfa95f3c42b4ef1244b6a3ae3f64f69b4f23af3182e837000772810a7673e39f4f0bb1f5e17ddd1898c05eec3f3444484cee3db77a58a2d7a640cf5eb8d2d43e8b3a1e32b9481923314d8559db8579c8883e2ce13259c93fd60e02587fca9576059bf47837808fbdd36e79b4d8384c9b71a25ef39527d44db493b9f6fa5d60e0343593f1b6ef659935b03db076258587c0d4521b3294c8a8ee5105a48558e232b673e1188edab809d14f3320fc36874128fe0af8a535147e27acc0566aaa1077e51730f96c82aa146b3710f09dbe2d52c35f1408cf619581af7f29a33c906da0729fc894ccb67a80fcace616ac3a96f1ab89400fabea127e574a2a43dde1c39beb908b1fab3aadb39c0404566ba6cd1546f258cd6124b5dccf78f9f21cf8be2cba607821297b2974bfda340e8fee6d793ec2539b9a0d39882e16419f51b3db1d832211e0602c3df622315029510d19bcc6787f60d069851f9bf3656cca80040485726a6cba7bd9afdd2317660006e8127c3cdfcedb4772aaa01b106ba534edefaab0a0be753a6a4ec171d68cf62ace09fa3e92b6e6a8d7bb6f0c01a3b7805af66f99589678b6845948ab1c9953a80873e0a5e70107e3b4c73cd5e2960f8a01c7eb100d886c9969b1f7d9baf30a89a3f2fe91f7b8ddb36830c0fcdfdc683a630d66724d8df629f28f1a969f2dc6a24d6b960664888eca3fd75967b83cd5ea035a04a7c20a594d089ba8a270c6c3cb121576230941490915ef23ee9c3f5e358361fd44d03a5f839e7fcff897873a2ca063cdbfbef18b645c8fa330dd558784841bc11743cf26f16a666955cfa642c1daa7f04b5210e4e6b685b31c2419533bfb3c9874ccbd47faaf5c7d712296b63d80868018baa54dfec5a1fc653e3ae2815a5af9ba52354604a30c1b75331487c9f853de2f48df653b402601b3502d2536e5e851cc05043acb920573c244d30b8c3838590f64e4db306093d3256238521904f1df7b825a670abf42832fee01594b94ea2c192109e5aca39b959ac8950e83b6a69fa5a6efd40ed78ecbd7a77d6e1eda6d0e91acdf62ffe953807aa695a3afc54df944e6db1e895f5fae97801036c5c286932650bd02e6f9638cb0a2f6cee48adf202a09734b8cc19e1b898ae49f1618ec74718a6a8ae4301a687b666332f31ed3230535bec9a03052d3a31124c835369454d0724acff092a00bddf673125f45e0a2568a86330fdf6227fa4a00be6f267a6c31cfff7065cd4a79bd8a69b9712fdbd15f7a61dec9d066eea961dce64ae7cbee1a3f3d9c0f58164213d02d283d5296fd1432a960158d0913026c93f942e796a9c6bff0bac228f351569cc6ad89cb5ebc7fc69e36744aa87a3d0d6ddfde0c094da07a2a7b25f62785eaed825bc0d91d497c7f94d347e11f7e79660efb0ead754b8c6252888f215321fca3788f17c7c49f0cc0a5a44f78d55a1fbf08cdcf6c9f6dc98fa5438ae17cab70e6997585ca7d0bbe533225a85570bcb3717d6f44d176bf77e1b11eca2e30c84c3dc1eaf4c25a0951f994edd44082e511dd8661e80597f16d2bfab95a96c20cc9f7c9a125ffb1db9b355488dff9d93fc22cc663f91dc27948f76b14bcc87ecf20f8f55bb26819af123633fd02ef3e96dcc1f4e0d245bfec98cf2b2e200684dd0bbbae1812c2dcaf6b16534217f1af87ab9cfe59ff5edcda931313e1a55b6b2a44157bfe438a03f2a93a36e0a2d83200c5e6ef6cd5770b75005e1aa9e6d122b93fc85d5a197e5d2e54ef8b042b086a9b59dd0509b6441fdc1381a9f9b5dc5959b79eefd0938f927610e1d72e95fbea89019b936ef3fa895a9ba9bc7e7fb1c64bc605dfc2fcdc23e021dd345abb7e586a6f0c8c546dc27900c09302c1166ad01eb6a5859f087db2b4a5e6f94acfdb34143985958fb76de1d5e0f6e33f6c00abfd964ffdcc3ef7481338650054dee1f3b7fdf08c04eb289dc3e3c19f985a761f32bd846738b285cc87a5e8f8791624dd0898c4ba02982cb3d7726ebcf1fd0b3db944bd89b9727d6f418687b1da1626ab5f30866d5928f35f09e97f712fed920bed1ad621511dbcf92a67fafbcd7123b0341929218633756908d489c05aae9360962030d2e308181920c5990d3064dbe98640ebfc65e22789de38a18eefa2e86bcf159c720f8e2dfcb9c5a673f995ee000c5bd190efc18d19b6620f9a3ed91c156958113071c9fe06ac7710f609ecd264478643e2c3ee9a388f53365ec1cf5599f6eb09fc327f81ba640c365912b4f7ffcd0f16511ee1f9a4f3005e1c2fd067dd5495d8d0d504faf9dd928888bc21e13593d9216c832a1a7fdeeefa69da9100a9d62e94e418f9878fabab8f17e1b645bf72d1951503162639005ca92745e9ffcbb99cb396cc8ce31a802b81ec139472fcac41581864e2c8b97070b591f728ce7b9fc97b1a82f00a0bcef613f590f47db3914e0019ec775769f3c6e905127400cee8dec5c673c5371c26b71a742accd4954de79e7760cec92322460f396398f613f1ffa7771fe85f4bd18d871461fefcf90b240bbf8382b605e4207b31b2062c7587b7473ab383c79cda2482150f8fd88602e1461fd7f15a17739e2aef3f189250b058df637cdbbb16a2ffff48241f167d5c5a3d55aebb7fdebe2e66aa62218313af4fb2418f5b9e9f5f6020e7bfbeb51bb23a1deb168c365827a59dc8aec57e5d3b9f6ae3be7f38bf0d3e03d8d48c1a639c53c4fc45e1e687eb3a4104864266b40f227348219392709f1081619f52bd132dacc61fed3f1933c833dd4996fc623276026b2eed7cc77dc26db463d8f786013023714a378b4c0a8b711d29290548fb254341c8b2e76c189966ec2d47eb6d2362a1b0d2b2a9fa81259e98b13c5c1162e957a76b0d1d11e63645156aba3c3de5dc443078fe261ea0864fa35d270b7a648196ea47fe8378d09650c3a9469a6e9d3f3ec35c293f4a78659c13a1a55f68d34d05409031fa79dbf421708baa6562af462bc25625c67850154178b0f0adc48efcd7472c97d9408909e36472de0d4f07435a0d6125a0e233297fff40c836e5bed902ebfd42f83545460ca87b3bcda16ba26cc7e54f74a0c607f6f62634f6dff117766865052fbc792d6d1b3264df25941e6f974e93050da840f2bdaefc91b5111adc02fb9937bbd3a2d40ef9ccf7fa3c355793586bb390702d5befe55c9b9a2029fafd9dd9f175d3ac109b5941e45d0f9ad58184b7ae62f24028a577d27e9f81744f3bb24a6b650c3e9c7fbf98ae937623b274afb30401f7f65a3a218379f071b02da8c0f76727909655e1166b6fe7a163f45335e9ed21d00872a4352c94a2f062aef83d0a58ad794ae3c61a8d9b5d33b26382f37365c1b058bd35f421377641c8718a66341ce8eab2b9d192be6bce70eddc2cf5a2abb29484b9cc32aa5f44cc2a8f1ddb62fa9ce02cd847043ea7b5a53528de5e0041a278cfe9bfd649507c331f9f85988ff5fd9ce7be3a1112b8ac8998e5f3aab82d35d693a7565e962dbad489ec51eadb5bb24fae032c70558818a555e4de5f3169dd385027161cfaabcaaf19967b15100d3db94b7eb59fe878d0fda890680444eb8b6e30b5607d35a1d799e02ae9a5fb8b9712986a05c691b57f21c566dc0dbfbabb793ee0ed1ad0e18c4689ef9cebfa2db62ce1710a58dc2b7b6b18964b38ec817033de91f4c29acb4e3ad9203c72d79b3e8f1ef4be5ae2411a2921e46f9f05ded3fb78976a526c347430ab4a44e513b3f970a38b1dce2323f42c5c5fc255bbcf5671fc418414eb0e398a689562a51cc2163de9eb052ec9b1f03b8e300fde6ec0b4796b1c7c2314cfff1355e2c1d390082d29e727f1c349f303e2e6a4f2cd370ad4d1842594f8cfb60dc9f083e4e37cf8cc0ff17e4d3411eba35d0c3f8bba7f43ec1385bc620ca60762fe6ab589ac015733dc9add2a2be88b48e24c32920fb1b9c5dca2176dea5f6b10f6b67c4c51348c99d0345efa384fd47f5b8684e68ce5b33f2b28177d7def9192b0c50ae511b8006726a5296c76d7d4eb599334d1844509c327049f0df121035e7b3dbe7416556e409bda35e0b9a97b75c86332f758f1e789576995e189f4ab1f92e05a20aa8d5b2db868d258599948dd512bffbac6943427fa83d840994244860c01867978eb6acb98d150ffabcb70bd89c5083a59d7edcfc22882b16d7ba30e0d928ea0063ab67d3fb8ef384f6061d6f4aa85c8e89e9bbabb2b27c851501ad41fb6017900259a34622e09ce33d0840018f346cda20e20018d439575a0bc9534bfcc39884146ce2db935817b84abae14b9c258aafb8d3457326c7b425b022b899330687dc4992acc433d913ad077fbec03512bb37af517ab1d60fec027b5bc0bc69dd74232cffe2a940d3a561df462dd21249a7a7f7b13bbae7eef7b7187af9bd965ec4f49e60c5668646e384247a305bb4d08df673cd745bd8ff429a8157c686cbbf4ac2342a723ad1e7eb9469e632e65605e718b63de08c78f86a56a9ef1f64ebbff60633379e40338dff77fe8727cb4aa0ad6ed4e836aedc77efc8180302d44d6319bef347a7f19732013088f8b44d91f9276e464794202a9463fd3f231e80aa740958f2cae6a79b8379a2b1bd1360f95bab8b65f39a0d5b1c9f7698d39aaf8118e5fba6de93d793619cb759184b6287f793bcec8b38049fb77ec8643f791685255523b8459ecb4cf88336143b37e50b83d2a99dd267a6abcf6f8be6d757cde2469419f8a07d9b45965af486f51249cfb7e6f9c8e8e269d61fba4ee8ed45c5e24a3ae4ad1f05bde524b7977aec43197afc5531d81d5c9e6df1cbd6ad25c449287c9800cd9d25c872d0edfd7cd106b4badc84bd7f91bf1c09f66fef0012604148b38fbd4447f917f65bc7bed6462cd567160af4cdcf1f5ad6ce087a3589799dc1303ef48234d02cb7b8900629be38f874c82d7d7817cd657a0d132aa38d694218897803e902184174aced701fb7f0790c35b74e3a9e04d438caef65cc3114178f8b512cab4636957fd01b65cd3f7bfbb6f825174b06bf3ab81c74baf4516a8a9ef30867179ac4ad3478422307f34e5fe42ed3eb2e8df59bf7c973a92c188a5328210b287fc85b595f1b675170d9832e0b3a1f79c4f457ed6d5b1c308fc6f4e2ea9ff3093c319b85a27b822ab686470befde3c4b2c5f5fe4f2a690ddb0a35bbc9964a378019bfecafe5a48b07d80c8d73ed95e05cbfb6255da740cf35b2037840827fea52c67c24ec8f9cbaab04498f9569b460e03d2fe3e6b67d914e4ee7c566be2b186d0d02dfe90ca4890ee30f84ebda75be7b571977409e2971a362788d3763fe85f384e5a11a2ec99fb902ab91d2b0a4bfdadc5f000783ffeabf3a05f2e96d67399efb85bc12602a672d33b21876188c001ff8c063f76dbacd37a8cc419c17bf6ffcd11a2f4416c97dd5470b14f0ef5a3a460d9e5b8052fcda3ff4af7a293460db0839c2fd2d16956ea84dec70637c948758c77a9f634e2e2deb8c0444a818cafd14051f721fe8afeb75a1d1a314bec34d9fbf9bee696ea4102726a44b3e89fe452653b6ebd3cf8fa82b9ce707654e559988341da5f77c92da0b606850892634081b728df31af4ba55bccbea18ff2b57ea370872cd846385c4a4077349597dae4b1e7c53ce939d09c9878b03e966e1d52538b46d2c2345965cc981df8905d50cc5b742ce8840f4f0f40e17abc5acedabd5758316a0b3a34d25c3a4e7f20625aac06e8f06a62ca6769db5944cd40371a5a7b3516ee9ca6e5f0abb8dea0fd13ba9c30aa991d82067c711be9b054ce68d5d336cb68afb8068e22cda8e03a18147fd761a41ee726c593fe2524945c0c740b3ab267d1093d012fc7ce830a4371efbdafaadf9d1d0f6f5801caff152eb47bc10460768bd8d0817ab75ebe865a9011c95912b1f83d656039cb5c16525fddc5bf63ea4c95f23ed4ece25d4ddb6827bbafcea40dbaeb6c25bfc8abaa19b676ebf0525b87c53a3666284baa4cdaf878027f5899191fa80c10328b1135aabe71c9753a87e932fded2ffc655dad18bf2d7685f4aa766bb0db0719ee8027cb69589c9b8cefc8ad5c1677e4d2f2bd290f116e463abbc51ac8a6815af8d00da37375b188884ebe55762ece6b3c0274f31640b73c5cac1e042f8d37578c6d4c1f7c74df7c3e83a67cf1649bf58f622395c5018a8d4c9d46b22348e3031bd0f252f2ede2b4ce0df51f6770da8a0e58b9e78496b63e661a03c97c1b8eae1f9ec7e914a7ee72d1e37cdc2b6a586a60bccd4953644c2e8580f5eab50620717a012c6fc983fa439ad8e77fe5ecdf068a42c7d3ce5ded82c517bd6ffe13b5c153eb1edd29509ea34e0ad8e6771580055ce9674502902711cd613de030f075d0392f903a8e779ddaeb34cd5a613832da3403870884560106c1f0b2223f9b34a19857ade4f267112d004b828b7e71f4649814cc8e3782e963bc17046d4773b67ff4795f4ba68e0cad2b93f999d7917aa0de8ef3d9497b3709f115259aea63bdf094de021491399011363ebda4739dd93c3f3c653c8559e34d6e92b0b72ffa5443787ccc01b74c011a020a7da2f1a496165b15a011bf360cbba6636da421e605655ebcc617a29628d60787b86b36691df912bab5e5fe0778bf3f8191dccba5039b6f5c1d1bdc94aecc7b8b71e18120067363033b863c955eebae8e60e88e3addb754a2c443b6ce7814124680c2d562c175c38d3b59935bae6802a5b3b033bb85bcea2a0bc0703b8b5b7059ca50bc614f0dbdb1cb2178a1f69a4b6f1e2cff7c6ddfb59a683046889e05178a44f7a35521e84046cc681d4047877e052b31eb78de5ecb76eaf29dfcffe6f0ba0d31e9a9b587601c7c07e0cab2e786bd2fd941e2773cf2846a6a2035b6af4abaac85c31c02d7f9e92d9758324c72cee354c56b840874b5b4b3524c457791ea38ecef37c149715f814f16733b8a2e9a255ae369ed51e6e9a45e65ade354c56ec7638e248a87c8a4ae82d7bd9f582717ae4d3fee0cc5458f936d9aaf6cd332f4197f59920c03bf404446ed1528d9be27823391b7d19f4cbf5ad76501249fd193e845d553c3e59d5ba710fdd80d45ca6d604b551e058d606c12406af37f54b323c4b99d51787334727da4d7e88838dde6da81934694c4f73f50ddf2d8e97f8fa3c501b216d81b74fcd7a7450bee61b8bf5db6ad8e9114c50a23ed5dfbad57addbae60ecf3b230f6770d3e9f610a260b041aa2e42625a5fdae65ec0e6dc5967b46450958613388e6b96cfc13d519a23c0d5c0dd96a658507bfaa0e657de2dda8c17f59943f707a050c0546ea3e7ac182f742714f092e3c6149b5f06e1afe3fb396660d39f9f51394ddbb924bf3a1f643df0682ffd65ba9cf41cbf2161702f1b1a173c6d6c2f7dd32a6b58b8ed754914663597ac969426b8c3db4ad8ef8bdc51d1957252cd232285c7206f82dbefeecb40d1ea87d655108c5f36ebc0135a5040f1a3ef9454df3c5c78e92afa3e5d14ff1e86d523008206bb825b7f9ba6c160685e820e20a73e500746a90ee3eb725362169e943f07045cc5e4156a281a6d45ed9472937e894c5b3eb0f9953b93b82159b118f0e17666d56163c59e23e66028ff17ed271447fec1dd3fce7c950ee87b3473456a9bc802f68334cbf362d08fd81cd23f9c8df3f39f0a8dd8529094d115e2023d0d50e24714f9ddfa9ded44924e23a01de55e950d8adab4af01d0b609b58f37c6f65d585b31e9ca5d3c1c434f78dcbd09f093f1c9d38d18317360ddce03e7abd6b841b54e1aba72fd1e8c0333e3ad61dd080dc02aa32e83fc054dda3b27aecc084679d6a86df3fefdb904f2dcf514a674f0a0f36aee1ce748657186f29cf3daa8f1163b05f049e4d38455318fe5b0d62855b48841491112bada50ba8291d94cf9aab63b6c97d7848f78e463a7c6a5d6aeae94fd9eeede5015b1fb89ccbb2c225c2bc19f08f9e39803a09d9d6192eac690997779b1d2da82f8a713f9cd7806d138ef8afec8cb6afa6ccdc2588b3563c6a88de8252d1eb5267e2bf16cfcda548313e914a6efa8c96ba07e64d49336ba268110b334f1cb3eb553815a5ac532f70fbdcd686f73fd9cede232464304e84ee9aa6d2534ac2fbc6adc551cd918bb6819681533e0308276cebe6089e3f288eef22556831f262ec5dcd2e7187f21375e4079677149861131bcefabdd1bd7de1be6a1204850b31b35bd4960ba0afcff86c5006e9b8602254c03ceeb603d0592f7d25791c099d74e8d412cf4fef3584df5c4d65d530042f6d73c0665424e1d133e33e60a69c776411c5428face93740894d29fb41bed376aee053173e61893dfbf9bb062939ea542ffa430ab2e05d2afdfcf9aa2d50dd724b5261fc04d1e1381c88b5e0f531a26afb5b03ae373cf24a73a1774e18f4d2c832c1206051b0471055dc67d6ef4138c60dd7ad161b0d09e9ae4723c1166228b98d79367e207ce7aeb58fea79ce27b2f1df6d44d72ae05f0850f4d6033d79ff274249a944bce6b094d743fffd7c49823ea9fa7b5bb0d0d734cc36253e7cb953d8b26da78494c2e5479762ff177b732c2d79bcee4628459bbfb647d16f9bdd71abfa8653a92553052992796b850cf6d7881ce3f8916bcbf42277c2bf4bfc545f428335d68d7d333d9bf1fec0091e9a251693a726867a15b989b515a3b40a0d6b016715c966b2ea42fb7ebde52b064e32ad9133585b4e7038a94a097e931192782bc4ed4b323a14f18a765af1e7f7d4750ed8cddd971ad78352a22a27c6bcb5d9370c9d164d883e71cb5dca56222351e253681e864fac26228f9b46932a5dcb0a2d3e9e9e4346cdea85a2aa5c993291f7abb4e44a11e2f95959004694d87f7388fa79f5a7cc8d990dc11c84a6bfeda60782d73fa434ea92b37bf79723f3773217bcd09e2b3d9c34826b6d8c0519a8b2734f30c3d4483a4b09dbc4b3dcf0da4c0eeafe2d130eac5aff09d54c430b126be57341ff2d48550a02c4092279e6a9fcef6cb12506774ea923f312a94b140f3290b71b5fd0bfcf6124824d5647750512dc2226cd0b4b942c660ab2ac16583c41f54b03888932ad5aea5b398421891e22f7bc6d894b326f22cfbedebf2cea81cb9a7978e5b82f3cba912a3d91e22336b6c13b4fd17e3ce2cc2881a2ee31019ae87fd21b2edaa837d96abc6929d540e78202390af41adac8c266b85410e7d63a8155132da77b330016c66456e1164be7add492b2f615bb75ebd7e26edc900c9cc3d58115a96e6426196b359d9d53afb1f64a9ffd974867e2ce63287c6fc17f6df0fd5c45fb0c2e19d95497104291afc8134c53c5712f677e3dc350dbd97b80b355a7292a5487870b87e9711d681bd6e0f66eca9d8d2f38834356913e2dbcced2578439448141bf40fc20265234a1767f8a76299ba16f58c86985a1fe6dad1f507985dc1303be418e677d5ca75c1159e1382849b0d9332472e780155daa22b9583465a966cf44cbbd1837ff97eee31393ba75524dd9a92e0e19d8dedc3201e3fb1f494c8aab8799192d8e45a1fafbcd3312e4a3379431dfd09083a69b381300b1dc5d228ad1322abe16aae2c3ce0ad2c08cc186355bd455ea2be152783909ed33d687bf0f1d423ea32c7cf51e31674232f273f91153c1be24bf8602e30dac798b5cc8fd53a62bb15ea1028189ba3219ee382b5f05002532c77df7a056400e593beca1ae4324c22a88000cee30ea31fa4cef65e559b3127200bdb885121e6b1f4d17573a7068cd1b6b86b5715279c3667df2841093d117a9c08b0116f903d4a46fb4cf6dd780bff6613a6e68e52c4c90c99c40cf58ab1f1474ff3495edc592553dab638f08e1459b52802406dd6b7aed33853971aa09e2ae3fbaa1f0e7cfa85f7f61a67ae07cda666205c5adc72883d4e19573e3140bddbc8b189d4f8c338170da24dc1608c5da415fb740ca88ccc9eab5f0876dde8e1eb10a1a92990cfae863d10a8d6ada900837b5571cd6971da4a83aecec3dbef61b8b88c5d3afa7e252fcad919051982d15c8261fae321237b7ff3a881c2cd622e824a8cda9c30bccecf2b239cf748c12b9c19c3aea2d6878df51851cb74401a6156b074858b937a7e6af837b9deaad27b61b4c643530a15bbdc25a85831de799cce1db56ba05c3c1093eca0487777f8fb19b8a5c61566c0018d18b5ac4e6129b634970f047bd6898fb44b85621672f8169ff8952a69bcad57392c09bd5ca23505d7a54ce8421ff07cbabe1adf5580eb58716dd26cce889da04540f33305832d42152e0d31e918acaddd67adce475025aec3466c94ccb4ce7bb4f2b084d509eb9696e51799f32306325f1b74dfef6747a627b5ea743092db5f3392445c30b7d9bff9d1d1890e35f996b5dd49e889b20eb7584b90f5a204c0e3bef389b0a25f1bf756d617bedb4dddb7f5accfc5ab5df06ec41cbc0b2e8c4bc08019cefd88cc2e3909eaa772cd425fec6d79d0e01529a328cd4fbd54ae55feb47efea41f8e4bc6b70ddf2c82d8c3b73b846aa5aa9a3d1fec4b2f5aed3fbdb3a279d176e6760b93e53e502d1e9e7510bab336eea12471b2609fb1cbbff2d9dcee66cca4d73f16f069064e271371576ff7a03b92784b83a3e053403550a510b1ab0850c2f3ee43fbd877a75f6b4430b8a27eaa25a7cefc8c2efda9b9bc704da84f15f50b72421bc507eac5a5e465931fb0b662098eeeb185d54f65697e61c42bd95278ef963cbf47c341be60a8dd6d18d71216a6849d0c443799ef5d6eacb59d5226843d5833d65434be18fa724b19ff5304f1c5816ebdc08dc2e5fb29599738da5d92c408830250d52d0476334c1907286717dae907009dfcca97ee687cd5601ac5cc565ab1691ae54915d5ee43e238bd265d5a085719a938d25140a33aa5b240df71e6bd4a53e2c458731845f2bf3c6e74fd3887e52d5735382661452c793f0ce668738afce07530b9fb2b35753157d987a8c4418b2be7c628e1b288775dae0c2298c0fa899f73764f84080debe041c0be73591e0883095508501180d66d38e9778eb2c5522f757864f56e3a108b4d6bb2fd8b77ae16b2b163e706eebe8f4678ac5ea7c08a052a28c6b9469fe8d885f42370f12759464d7dc50b1055dab63e47aa41f7493d7c639090901d4a98ddaef8308b5c79487f0a705b2cb47133bce764d4665156d4cc7be7a67c4dc99217a3a6e1ffa45292e2294ec05c7a04485ada937c2041d907a3541c5da8c00873f40fad76588b59b73f75dfb23986a26ddf7cd1b0294584496762b0f547c9736334734f1f6d688461f1d72e773aba9608836f371560ee6e7aa9373a6ab24d158164659c4bed5039e70c127943474ca183653929dc9f80e5a6b97baf57041519a690626da7977c156f7c9a08eee8eceb7403905d3fcb9d9cd8a7c1bd9a4104f661189004fb9750d28b2814aea514c6c03075ef1cc0f3209c9ba5eddab7f1b28eae3b42fa8fa495fb6a0ff208305204b24bd1f7a7127d489e05b703f41633b9f05e60531a7e05679690b12326418324a4884f71fd55d07b972ba9d1de64aee4b0d0a332c1a6ba1a7589a18d6c5e990be2d0bea1343c81a49236c09f30efc68ba687777d101ce6264291422b41dc6484b40e8b0d1ce4bb9b281cac1a44b20f228c085d3a75ee6789483b4bcdd7800099e21f02cf1442c112f02be9f4db18fe2d30a3ddfb589df9cfff960e7fadc810c5f6d572a70d940eec720e50b203c51cdbf613da28c3e018a9c76590ae3e9174051f105e3b04c132516b297700250f8355d0043a0464e7ea32106672047ddb0fe8cecd69dc26006e8b3b39ae0151b3aec904f4b3fccf3b7ca1be77081e46e102e4a38bb387a2e2750847de6524ac6101b045bee13d6fecd8caca880768334a41b10397e3193bad125a8a20c73b183debf25910402b847277eaa30d419e8d4a4145ff7631bd8c058429ae666389e8cc2894d34ab7993bcb9192bb9b621bb8ca4d2cac9f1e4d2493ec1456e111ccf4de159d8a218231ca981bc274e310baacc05c478e4c9c9c996f97b0a3705ed6bc695730a4536250315884b1926dd5218a9c31e9d977f077eb0462736817337203b0a3bd5ae2e9d5832cfa6a8753193718ec63c402bb1a37d268e1acc7a277851d7c3f90eb27cf302b9d6645db04b45165acce1ec2874e71e90551b87754ce0247b855b1df66e4e29b84b49661ff7501bc153a08e0de2d010b8158a129483307a19d6add65de21938ab391d43c692b16d42e2f9738516f77d1e388d491781cb9c7e691321947b0e5764620c0ca5d4adfc01adf5aacce7ed02ae8be53e65935611f0885ea161450ed6bb2eac01be9e448297d6e3d610e8192a5c1b1cf28c9d789c1fcc8ac740b88fb7807d9bd5a859f05db9f8a2ddb4cb59fdd983c76934f925a5aba28a49fecc819cacfc169e8cca3e1bc493e5de4b824daecb9d06f8bf0234767a729fa6f7bd8ec6460a0db64699b6c5ef29f522e5a30e0dc19f0af77b7d49772670b76a02d131fd4fdb636054fdfef59ba5f47e984e3fe47592befb58324d10434fb71688dcc27fe1f3329f4149c98ff26ba282bb7f63b009a482d8fd39d6550d761d8846b901cefa6cbeba4a891b298e0b90ab5a69e356778381b272fd24a7269ee519853ab27cd80898d3f1d86cb3e58f5491f0b465277f739cee88ae5a471440efc06e2b293c963a77f310613053352e95bb9872a0ad86d472f3068171af536becb799a3fe68913a31603a4272306ab20ac00bbf17eb41ae62bb1383e50908eb6acccf8e8fade58f3cb4729b723a9c4c7020d4c65c606f3289bdc8f6aaa15ade0b2046bdfafc3a0b2d0a5d6e4ed377ad755c5753010cc52bff264a3630d999daa73d05e1c04257172dd5c4e855d6963834536f6f0c353ad3c2537754a82f428c7a2667bb8f61a73585cd147c1b9b7069c8932e470e34b761177676e144b93e34176dda8b300ed33d4fd72fa6eef4b2a5a0dbe9376f1b74ebdc20b0a0d54b2a6a9ec1e2616c6a5080a3df44ecb914e74baf4595d02e9688aad63a4bd46ca79b4e79e16898a6eeb5dc16373d1b25de460834c67fb6df6a519b45d6451c39767301028a405870eb6ead986d5a6b552a591ece4739ae9a7d5ccec9b1b338a1c8740a60620e0bbe752cfd28b91f888952e53caef0e7a64ed6af6a5a7b9da419a8b789a13a92017a9d02ed2a30f743b99873e1dc3cb908a7408b1eb184600be0ff9ba4190a34e0a401d13744274dd6fcdfd97306a2fca6c2484bf0b3be10405b31888ec52307af1576cdd6146e082d68b24cd3aa44c264ef772c6851742d8e9a3ce4eec66312b71196a54b2cddbe1739a01dc696647cb895d6b02fe3a177a1bb67d3776bbc04a0c13dff76a65344720da85b868a7baf4b69c367d73f674e782f69c25657327a5f976c7e7a2d53dc2872deb71fca179dfdf09ee43faed0418af0ad9f247034b53809234b19c4aba34f27a241232c55ef13f010b92918b55629d5c5960c6fd4d1916f2d3603d39153d7e297d8d9f51346ab79821bbd9dddddc75c219d73ef1b0f0f275384106728030180f4fa96d2c62440f3a2cf50d007d917b87130a62e15cfe1ebb2d69cdc89d3c795230874981362000d878ac9c57fb09a989798403c2fb6b13834cf6495d854805e71b1c3bc8eecd9969a0570e4f9c77e26454a4d33ea87354f5f5519fa8a0fdf9f7de5ca7633634ee1e19b6281a0f95f9bd02399d204fadbab6cdf2fc3be1e95a17ebb6d003595009174a86619817feb7ebc58b51476244eb02ec7fc087003b0da4bee8650bbe296e5dcee6ca553e2f2b53454bf9fd02dbc9e00bebb063b42fdcb01ae0cdf73b16b853d8076542a76c7ae3c21ccfe1c8d53e8c29d1370d3d055c90c006182a5e2a5392628fcfa02d119cc0de85beabce4b42ca46d544f1e3dd64e0097baf6f6fc12e3c83ad2341958c7e4372dc6e9bc7cf8b2fea36b2471404b7a5e0dabda4237d0049c3cef0784186e2f25152163a6fa984ca770397c1e1a66031ec7484d06bbf41f183f2244f7050a40f143f9443260f6f3f3d8b394c68299cc8f9acfedf91124bcca78d395fa73d0da101bd50c530833bbc31a88dfd6315327a1e4913206d038e9a1d9d885a55ce6a359cab11dd5b69d861d29d7e6a7312ff04c088478f59894b1bb5b84546a76787eb5553433e3388e891904c073d729f28defbad900166d0d6154f1968fc8abc80bb70cda3f9c2379205eabf22a30cddb6782cfa959a6e6d480f215ca4902e84350703cdf224b407b1af2be2b9870f2e9f84c6d4af76090038ca9713dcccf96c014d27d58795f21276f9e8e34600a766007eb24aa878a23a4d358ace319c4e2d33bf93750d75f05daff68b9b424249e26911a4c2a3aaafd9b80b08e2e6c9d7d56079968921c8a8f2937c586ef07bba3d0d3399c5e82f394ba489b1a420bacf9eb824557edcca61191ab797ecf344f3e20f04802877aa2480582f0391b44dbba355c8ca165d1472c322dcce6f2c6e3a6dcd03c4183f294627ac627a88d653bb6fffb6ee669df84854d280f99f18c24872b593bc01812dd79c7cea065cf0bcd7ba95da2aa8276b7cdde1fcffb7a83fc3d15a062d2c069e63252c0fe25a77c4f4badfeed4f1d2573f3fb0a1f25facbfdfee3a0b118d48429f270ce79a12fce385e8ce3f2e198439b4d9044bf1122b8c141050838c6a1d6c41c4896ce80c6dda170832f1ae2ee459b457ecfa5376a640d52067436a78cd9f66ea50b5d21c5057602d267cc7c4dc3b11f6450cb42b08217bd264015b27bdf73917c8bab7e0e71316c09a2a0e2dc91832092e74b88884b6e2e6afff5ee5dbb7a0d459104dbf4cdbd3667fe518c1cd8c88a939306f4b2b6278408215e7e5468dfa6cec195a3422e402ebc6d31aaebe47675057e20842816d49220304705335b24ab5da17065415f8c9ef5e3c42f195cd1f8af3ea39bbf6793c32ff86dd9d515e3a8a1fc9f35db5ec4071e01ef485a72ce9801b8ba732602f9b67e3cc84bbd08a6a8c2cf4791db4f8b9e558105d13517f5911cd1e0cd132cf9a8763ce0dbd45fc1427564ff438cd190574448f5819c50227189810d7bd1ea944d908091091af15398d66d687cf88fb98e6e0033cf334514b93c061e2269455f3f466c7f0d3ecf2f436e8b5f46db01a8c9664882be3347137ba3a5e3f6ef147fc3e6ff34fd9a820a29cb343450a26737ff5117fb647519e29fae4a5aa46534134318b02f484d4f6f320dde2f4e998e5f08f45061c2959d02236307824a630bc46689952d0f3fc2faff4f0f3bc402e159981458d64143f2a6e73abecb65189f0dd969fb9e7a5d8f8da40f173fb42ca4cbee37d6587d86775f3510b07a17364847b8e37190d048a12a7d7c62bce33884c9f5590e09045f91d984d93633b2b09c2f2c19cf1c443b4b1da706731e256d85e16b2ec74305c68a88dad6b9271b25e74e0a978f1e75ad2b8aa1b41a6d2dcb39fe52a3a0f31fe72bdd54cb11a47574a1f0528c7f64b977576ea04edd75b3476834a3e0e111a6863b052a7386bb8adef3c8bde14a1ef3de8082935bccf3f21ddec137970090b123395565f3f58a3e3bdae601fb5bb2b600e7bf3cf1b5a899238d8ebcff3ae65d4d1b1a25480c7be791274d36de1a5b04de298dce8835f42a46b862424075f20bc6cae32781d8486d9b42b67fd0d50af8bf9a7613a4e4931ff04c9014daa3eed9a5cd06565afb8d17c5d44b26eb1e5cb7319f796b973e3298d84a6191c7317b247200be376f3990000f315cd7c169f7c96413b3307d81802539a643d8d9dcb89f8293b087919d73891e4c15fc81876946938c387a218d5c84827a2e58218f95122cf28fd544327a0c1d74dc8b2a1a20c1c2f2e587764211e2685a0be5b01233f70bb3a824efd93a5c24deaaeab1e8eef1093111c93f0a1e5d70e79060eaaf0fe9f68637a83164e0499ac57baecbc294476c62afe578f320fc1281b3786cf5efbcf73d0dbfeceaf12578f77a8643d1c5e45520e78a6b0e3542d57f731063001633f8f19d480d27248e4586c336bb0fc4fc77b5ef58febc00021b8d7553d51de71224b611b9b98000fa33ca3f475723ab71f93f9c17776438051826d5ad5600735ae31fa1516d2ce6db65a4ae7b202637605f7c113cf95eb2b0a5bf197bf5854b6b493bd1a327b52a5427189d5df00c216a3b0bf99d3b7c4cfec62c10d3725230d05463dc474736bf4dc3587db39c35fb4cdd7db0d51654f14f356a8d3b3acbff21511a17c31cc43251a40016741e36cad81f58d11130ae5a991c5289b42fb750553a7ad2999e7ad16516c16e27782a97a341570e09e856469c14996d4d4165263e1a5e6e03ddafe4a7efecdf851f78e4c5fba158deff7d9d59ff9872869504a7ff0cb891039aced533599c254261704f7500084e172f8bbd1ad5b5fd297ca329b63e26edce25abb52733300305fda771ea73a8c9e994550c8a77512296ee5deb800589ebbe66e4478284c756c052193935019fd6b8727e1e26b819e9cf39cd70e677d9e67c4c509eb878817e61c442697d3f762f4a21e03d641322a2c4349e335a511907b3a6742063663e9e2e08c24cd9cf4d4064aaddd3d04bd53c2c262ce6ad861d1c2354724640afdc60c73f16efe8ca498bacd9baff101731171772448edbbc68dda7120307a871bae625c8ce4051c777a12b02e639369b733a8988a3d54bc779e0225f9616d45bb14e65f8ff85a5181e1e463ec60d9d1514b958d088cdb822e1aabacb2719950e93691e333a3722a1450c0b01806e0f92fc51e4b392a309d5637739463c64e4706a0f4fa8e166317eca7f90f88a347d0efcec622cfac58703678be73c3b5daf6a604ca6650be760ca36c0b82e21a5c28da7c5b795a1bf0c98d906eed80a9491999ff39581605b355db54de3aca9f8cb8dff7d0fa387a6a8272c2bac2207f43fb1c23fa161f2ed526f3224db02272e0f488d99d7e31b6def062cdb829d4b56fd9e3e7e71760a5bbd2556919e39a4957f313ff61ecaa2f3b59ef9e55cac0f65746bd107c8188496dd6346cf804c9290847add710dbf2dc11c37a56aa510c630b2f9807812435609db2e8623125bd55d9f88bfbd62df6b9191c0509aebdf7606521e5ee6a2a6296f7a46991c07b8c471117a6b8e258bf6415bd22a97dd5ec41a0e6e84f77c089efaced6c03be33d0e18ed26149b7b127dde22d21564a4bbbe7233907e38abe96a34fd1feb7d834ca2b8d9dc4fa1bedaec68c04bdc421a024ef0dc8d79a05046ad640bc6455543d2e56db9084b5907104ed29846694eae24135be7dd7985b0c1550d90816ec5e04d26a3fa1def71837da4c90bb682581368690c1e0996d5942e0a20ea3d06212323c553cc4dd6f1dbd49d2812944d6be7d740ae80099cf3a0bb8b5895fcbc46c910c525f823d02d0f8a05da85574f777e96ddc8fa1e22d87a1be175939c3192c786f83fbebbe006310e3eb46cb0f0c5242b61bf1f25a602562a5a68b96b8cea6b449aced9193347e018ccc852223b3e5ce7345a4a83bf425914d0e9e0077e00bf68a813db65204c250dffa7d95b6e4df03669d750713206851c6d369d038813af39a36150fc1280ece1432708ada5ffa0c284f1c89bc32dfdccb153e594924611402388959cc550c3e5d6a075adcb973b9bd09220d9d85a884711dcb33c2d8b57a4626fab8656dbfea5f63865e3676d12578a9bf80a41a4e6dad061998dbddb96f66a24f339b9daf257c08817b9f0086c70810a396d90a77139ea263e92476973f33a7c4d83c10ac14cbd2d73c32ac29310d6c993a33d37cb50712711a4c3f852e8d87be886f346073006130126bf1be700a014f5b10304c111d45f3fe5d7b821d96fdafaeca816c2c18fef89837c125c15d6ce551edd6865c0d1ee712e42b669d07a2f5b99ed9c1e02015a004974f025147efd15ede4887376fe09e902179485079686a11b10e039648e0da34b6f17526f57d6f489a6b5b5739d2570f2cb40e3cf2d40b9e5dbef14e9b0e883b0eb1e10aa8520b4817ecd37307988909e07559b5c114a58267001f2eefd856daa28189ee466be724e07955d28091b34ab98be13eb0470918ff4e51fcf4dff43a194dc45b1ad55ac94009c571841ea09ceb5001a4cf752a58ff074e9bc1b409210596a0711d41e2fd1223e4a47be187c1012a5c215d1442c6283788ba3b2bc287083b8139862752626dd293193f941711adbe5fb93f1d198675bf0ff1de6b6281bcaab5bd216f0e6f71a005e4dc7da991438983b8d95bdb1535ff7d2eef0972d3dbc0e0c673b1e32b0c92fdb95704af82443f2de098fe46a857105b5f158621e42f0d1fa9449216de5e75963af311f7c4984e9d4b4c1881b058325a5a303e0ee92f5f94401580088096e439fed25293927143f362ff71c5cb080e149a74234203f8a78d027eb1439ed9d9cb59b05e867c3ea4e3c5b31c1094ff03b41eeb2e2d280e3b98833bbad4aadcfeca9281a8d663dd32c4644c1424608ce0033b48c3720d091173cdf6ca005024f4e134575033ec66c845e25ed0d6468f6bb21af2389590d4d7730bd5ed917ca00f674968ff239459457b36ccdd2703f99aa6a1c93913a99c80a58941ba14a7e986ae4b1c867900815a44531071d06a361a62ea2a3f48ec7a230d87d8f1766ab8093bc80a60b7213c9be94e1392430cc8275b8e6f6b3b500e67462a26fc1bd8b4e525488911f44a9a6a3b8ab3678d16add153c206e8dc817fdc054dc95e78dcc44b1dc8ec80b7f4f92684dd255d6ee4fc2800fe0da415716e614d49da9f6537e2dc1f0a7403a28b4df8f2f81cc09e31d7682b700a7386ebb7582d11fb6d3c6d6d3cff455990e395848be30d95ddd88a3539fdb539cf9ba25a5a0a3b5d13b3c9591e4617234f5e64bed41ec0b8952f197a6396875f10772d281b5fb073b3f3455ba889c48cad7e742407a8a716d2097607cffe2020aa80b4faa19ec743752322703c24472fc183bf28f0f104243a687c7cbdd77f40a95ea028b2c847fd7698977bf720ed2d5bd689d1f9b1b041c3cd48230041dc8fdac85b218d981f8b7f043f7c6bdff43275f33dc04a6374171e548cb61f47c4fb838a29f992790d1797643147141aba9ea6a20ac99e2ff1d1d6a22b5cf01ad65aff20a71ad36c2c0173af89c4658e8c073f2c010189b295cdaa482e7caecc6206d857c7c620022c06b69762aeee8ae8adeafd8dc089777efd175aea8bdc36e68cde713ba87b345badfdd6b1fea93cc3eebb2aacf5aca4b6963ab443609064663415b60bbea300027c5f97c38f70b25cae347a564057fccb05c6b2e8c266a1b86e7e468e6eca8af3ee3b7af7fe432e6a65455ff598f9b5505b5fc5b63b51118f30c26685ee247539d5eb75f8ee946c122007e593c83c5d6de48eb4e16135c612c9dc258f15fc0a6142428f0285b34078910e2a7ecdabb83673f4d51a877c370da4bceec7bfccda12563ed7447e08a8d9fc6345255f3c3c6ade59c2deb2ab99a1ab35c4ae15f555248cc82111308cb8be99291b07a4e3e4935daf93089046de139addc9706a42982a9d4c2620f9e2a401daf23095ffc6e0e106661bce0467ecb3b4a60305866162c19bc825d3a9f3d8f5ce8f5fa6c1a3cb217514b95ba9194e46e6925da9f8ebbf7203f82787d70b9abaa6cd7f2acc6e332d662366bab0fba4ab47c29afe2472de43d0424bf9758d628842fa2a42ae6f3749d3047534bbfddb1df1d8afd046e3aeae9f581817b846cf322be5cf18a42eb93d0e3906c1b58ff034117942c206bf61de3b6ef0263e24f773f866f516844a83bf43e9c64647141f7cfb75af04eb5bda42caf5ecfef889c901507782d12137c7555fdd6fd1151b1dc1eb0e7e2ceaabddf3c0ae31e6e4f7a8a546bc32ae79b29ac7d1a50a1b70cf27736095a2ecc0f532fd564e4c6a1a2d4131903e6bae1ffe107bd1beaded6a12ab57af5f3a11c0f5a0cd67b69d2a835b38c52eb66573a2e23c4e3a18a2c0c6bf90f4ce0df04c5263a282e9b0a582902c406dd7daf61ac6bde63609617a98408e9d1d02b57e8bd5cdd67b5becef579a85d821c02191a5f46a25480bf074802c778a084ff7dba0af4b6f77aca1c4365abd13389467450997d995579c6c6932961781adfb582433128bc4acdadc0cfdacda73b69f93296047a265fdfa73fb27eb0f10726384607d1d8a88e848d"); + +pub const DEC_32: &str = "5d946235fe5ddf659e325ce1f6e2d3ea"; +pub const DEC_256: &str = "c114d69bc746cce4978c5edfd9be212f8152d2a65eda6ff38c82225f7401e5663a64146f4c95ec3966f6b3939dc919d580d0270ad24f0ab46a28dc4476ef5a0032414e717e6c9001426813ffb5e235fe89aba9edf7b4123688a5895a2fd24792db577f51eaf2ba694062b55b5190b52ac9db63501cd12c4b3f0c9d173d1a3aeb"; +pub const DEC_2048: &str = "2d50c80940c202e4ba799c6dcdfb628577c611b523b30188e30be89a5c6b3fe6da45303687c631cb669a8d56e4c6c4a2261ef06351738e9ff6e31a21e4f9851ecd489dc5e69f0f84bdc9f6c60ce70762f63004a7a54c673e91bf6da8876de0dcedbdcbcd6128a9047b0e9b087bcfce5cae4bb9ec4f8d5183a8633bdf8c82712315fffe555d0a11fa48cc31f0ee6e7ed3f4f6d48eae4935d4aaa3c4df1549e0964383d533200f1f4780aba317e88783609c3736f5d6ab7680dd0e31698c5c045dcb454667f5c5583797230889d604b7dfc72e3ade9adda43c27382e82e6aaacd2f1921b11f076e3c1dfe06865f42f1b89eedd313baa92abd57ace6418fb01ba57c60e6cb626982ed9004423655eccece9accf05a1f30c26909bf0cc1c6b0820127c89abe1e7fd0e9b17284d7ab7ec3b245a56cb857af17a446c48be6a474b29f6dd47b155060ba01ca1cd900507d071d7116098dea5bfcd728123c3bde92a790aca05ee935c45237f60d3fb385754c00736115e79774796376100647919bd6f08db7724a53b8fb8124e2be4a1cf886566de78702135fe5b6cbe35e054124c2b31d2f46aae4dd54801811360ea1a23e821de1082b3692ea5652f97ae191ee6559d278c45f49d150b825c3cf27e31faa7fd016b13a82f17a07dd73f999d4e49223bb32ab967779d057427a0e64550e5b4c50bdf3db89aaf631ae96da29dd865a28b43d9a10bf67fa13edac2dd7172609751498c2e8b4b8fcf7b875d0a6dabad9e4b6c0b8c74ddbc642122729fd6e8eccc0ea40526925f84a00093b7f5184f4c1c2161a9f8f58efaf5078607478185596f5512a5258fd4fd692bd0bb0cee71245ee13f30596a4fa7ff845661b125212ba32c1e88db722e43c5ffdfed99dd32e1413855a64327ad13de88e35be2c376a1d2be0c0d325c1e050d41e0eda9c284944140cd6ca5ba859212ed8e09188b1b23fcf4523879095b1a7bad8304aebb7f23b8beccfa72f70f27ea688dfead494c814209baed67d7dc424b3a0306c1b4c0e22ce7c379c98f1ea7cfd4421aae1a0c51c06df74d39a3b20cbe96acc1fdbe3888e1c42284e7f3cc2b1196062b2612ccdb2af4a0aa78161e537fd8c6308e6eaa8e248a8dd89d52734f45fa1dc1993022a448dc1ea12602e889de6bdf4db7f9ab1434f6bde85abadf450697fcd93da38873bb5716eddb1e91a5e75866ccfe628694bc4e8cae4530fe60684f890bb2c7e7662ed214dd181cf69b7eae0ae6a165b304e7270c8a06759241cf07392f89026953744a9f53c9c8145998ef0fefe88b849dd51db82de1949b3cbb2c77c50e6b6721062844281ede116fb2d4deac7942ae6b1c9cb4f8c4f022ab60fdada47660f8dc1cd567d7b79bdb84ed5b22c5cacb7a7a4fa0e35238da372611d4ad716156a7fe7d507e9ff3b9a5bd4281d22d32be452cba0f"; +pub const DEC_16384: &str = "e040cd3a899a6cd5d24330d081f254a0d416e634e90cbd4e6aa317f813ab7ec05ce1dc14137a6e98bdef8d9b6c83968e9d131eb035146d4503ff7c7b6f7348e39c7dcf768dee6990d62e478db52124a05c1ca34ceb898be09875afe9bafd22fbbeca8e94626153d5d38bd5d611363a9cdcff9188cd7b08f1d1cc8c7f0883573595478d6a86af79bd6e6cef58e776ad9d263c86afb1bc672fcac5109ccca254a48aedb98882695a0cade90cad41508172293ee6c9ed1590b702f611a65948f2a2a9c6482b97770016d9e8bbb6e5942c42e0d41c89d5fda4df1d2c88ab15b50bbb1066de44cd4770ec9d133c4abc507d09f30d4d4c6304f7348c8dafa5f8997af5c54de161e4374655b4c517983ef7d3bcc3108dc44122680586cba6584a08d110428f9de22796acb534db8f72a0333568b7e0cb0760816e46755e7f30fe8680601b407f44bb4ec3aa4cf29ccbb319ec93871bdab10d0b96660f622588d7e526f31118474b425867da4f3deba0ac0e6aa02f05543872afa71a21dd3c0c72566c796faabbc815cec84a7241a803b2ebf4472611ae230698e207c93f0f7e382ce1c753d74636383a41250f94c715f81a160539a2277927abdd637c077f0eadc0dd771064561f4dc482e2d058467b37d811ae36d4282e268f1820d0bc9e3aa5099f9c98d595757f559f7d321cb91d01b4ab1b8249ca8ff76e48b80818c6912933b3340a77dcbdf94896fa86b3cdfbd4901a6e510c1dacac0e9be315b8a3ea837267dc2e7f8d4659e0bc00f7a27942d7e3a47ef1b47d64e6dd11d730acb95329d8d9cf3d5d5eaf76e9161d43f4ef57b947bfe7c09599704faf220893b0362cf2cd8db83c969c67ae755fefd97cd843b3a8e11ebaf474b4375493fb3c5965884c534ec875d5f49f0776d86c393dde00d7bbba257c51614f135d6ee0e5dd5af06d5a53b744e0e2f564c8d29746cce81dfd143273c3133da58cc7224484c7d5362711054bd4bdde6190127d94046624c8e7f6aa898ebc971898ca5bb61bd23b1d4d4bff5d56bf46318f99294667c8c114173fe57a53f33359dd2000f55ff45a5aeb74e15ab76c17605227b8c8804ca37db65035a6e8585a4489b270f721a6d670026dd9845221448dbf2714c635a97b9ed59e340c1beaa6efd307587b4c4a7b2d8a4db1a7ed3f52e90ba76324e14bc146f5e06423910a531de808e2aae25053730e0cacd1909c58a1cf0818b8e7c807dae0a6de2444c5b35a7d834bd899fb35725c1b870f0ca94a4750004b36490c5feb2a6fb67214987b786928597f70fc62541979ed2dc36c4808b05a2007b11b95c716be17b4ddeb0f48670cfcead304b2f353d2260f70384939a403ea63a4f01c8db4e8283aac97205ca4996bcc737d439df60ee1177f647654cebadf40e089511b498b5ccb4b04181bc3fcbbc4b83755ddd2fb503ff7f422fa2c2c9333ac8798cdc2c0c5601a02eda5060a3a738da9c05b4ce628cb0ac01bae902bf9794a12d9a5cd3aba7e3e5bcda4ab8468e84aa8c699576decdad98287afad0a3b8a6503150e2f06c9658014e7f4afa3734780c43e82a982d4b01597263f2cba3090f9fe4106d75bfec211a37f1a138088cad00e7b842c1e5809e9aecc96749ac3e2ec8d992d2c37d722e87564522206c74f9e32effb2c9156152d21868416059225a7d31ba7508b51a869a676691d32160b8a68b6b091867e38d84a6e11deb4a3ea439fadf6100791d47d91ecdf2fe7d44529e610b4ad82aeb0fa0e27cdc3fe20d9f3140a52415688b93a8959c5372f072cc3a611d7d2bde23faee921ca3e2064840e5c4b672261d58321eb376d71363d588dde246cba1ed28be0689e634005938db38d07464fc94045addc5e6c125379b5c1a39b27104b8e3e4646e7268595e77ad4b4a9435f9fe76bf904b3ad5b8553cdbf071dea854d199ef29255317563f41ade0ff6157cc5826bded26aae77ee2ef0dfed7a04c072cb7dbedd2ee578e4dec27bd8ffaf9232355cf85001be9b34d6edef182da99cf705dba7068478851262d806e5e3f6bdbaff3989c4a61ce8c12b993ec8a8dc4df24bc180b692c3287ea561180a9bc8f2c9abec9f414993c00de730c5975b27893b53a2865ce6521d4656d16eeb2bf5e29c00d0a2b7f92129dcf30aa9f20d9381ccf7807d4f062cb044f889ba4770e2d5293c280a3d461342ca6181f45210d7dab62e6340d7501dac2ba99c124693ce9f2f37eb1993d64692dc4e53060e8bf17114a8dcbcc64ca4847acf9ff461d14e16faea856bef914c4f98a21643a98f3530803b1d20a9a963aa811e3d9d04a372fa24b8fb212a715221756c4b0281da673a7c9b69f11781ddbab09ec33219a6d6b4472b06646c7fa725b7f24fcb77af5c70538789f9cae04270fbb70c810018ac4dc48b59d7e3d30c7dd187c17ce1e4488a554861d0147f2f3377dfb8aada5b54ee6fbef32fc3c9e8f8e611f48d9fe7af8575ff62b5b9f8f8e91f414d3bc1a86c8ade6f05d3b9f2d4e6fc838e6b4f219d3f7dd177fd20415a69793a83e5c823bc5f4ab8d4783c0f6a284c88e4fe7d0b45e995d7eb20e90a4720fd4f7e709f8a7d9fab009159ab260eae9b47d0cdbf3ffc854c42a9205f10fa072bfee5c42c0f1aa972e2e40057f03268d4410108bb074d54e26d18f70e9e59bc5dc4dffdddd7007d788a2b2c93f326bc92f908c0dd1293fc36ee911ec92eab635aeb56923e91225f343678e2900756779532ac2f3801d90e2c2bea5b16f43392db7b5a97d1462f42fd32bafcdcf9d450ee9eb990891948516d8c1ff85a4b2df4bfc389ce53359f66cbe5bb51eb67da7b7225ea499c34dba20843d22abc0d2f6cae1ea94ba95ce145750077f6de5ff3962c6bf78092d1386c1f5722c5ed6d31e6b9dd85a804cfcf8fc13d2b10cdf5a53089118e24e867d6a43e2ad242dd6336bf315a80c9b9c004a8c25abbcf2afc8bdd5ee42d515c9a627649023f1670f55a9af96c686108943e0d91db7b26d53efc41886207026f529c65871c1909d5a71e99858409a86ac5ed6f0b29dc7d9c06f7de758e0e9bbcc573386b85f0e082bfdad226864ae0ad5c1e45b2e262a135a036c8d8f9508f3bbfbeb2b56f318833d3f30ae9fa630fb7caf0d6085ced853bd72531bcf6bf86117dbdd05d9fd28feb604c4ad28e824d79a92c5c52cfc803564c8a75a3fca3df549345cae0624f7e4b9f4ced6d51d30a7ecb121642e767b2704a97bc5a1e650864f165c3115453e9b9ed8c326ed68febaec9f0bd2d4704bcb7c05373a5ddd2f96b5342d58a893819e118fb5d921a5e20a30e2962c5aa8f5b4352ca5ab1779da0882eb5ca3ad0271172ffb63bda7bcdabad18194f839b03d8d92aad605401c57801630f79e39b340f4fa48cf0ced8d92cc418c667c9f1d2a25fe75ceecc30ce0bffee5be98b37496eb552dc2dd3a08cf37aff093f7829f96e7a8c7c5c8e93452b35ef636fa759236908c4b7fb7144f4409b3405ac2b4b23d8da0212cc103d4bdfad06ae01b7870de7d3bd707c3348fb347f5e982b5c3b96fe9e37c41b5af4ccd80cfa050e795289319f5fd2ff1a6f191f75c850b2894779a3b12f3ce2f680c9a3cd37f4ecb4e3f1f4dd343715ac2b782cabdc18c97514ee9fea00db7f01380ef3cc3a6897b76d0500439dd56bd01b25c8aad23f28a5219e12dc8c3d6740deeeaecfd7df5774822781c66dbc770ed85266ec717384a789b401bb7e7d30c63d0c275ee4eac9bd713dac397e9f6275b6445d4ae11fcef2857683c549cec5539f359027728f2ae48baeab42543cea7df9bfc5325551b0777bdda2cba6c0f145465d752f3089908699fc726e8a45ad89d5461ead6460f03b0c56b3dd7d14d988d91bb22f176871f9ecb980fa72ab1e4f7141019bd5a6fa6a59ff586589a99fdee589127b47dd5e74d3255f5afa3b3332d1f6adc677654a7b5861846e9be8d84d316aa9d55386f4d09212074da38962dbd27fd75017e8e87c5f917b18c52f53d3f0a6bfcbfcbc8f871a285487f7a5a289c6fa85556b030596d1a833c50d5391d92079deeac838bf64d650ed9a8c3bb7677ff61d345450f56e4b58f1fe546e3e1b07ae14eb09e88feea6b2ad9da1f6bdcef659616f92c0c292a75c53f90ad31c43cb72f98cd2133850ffb059dda456fc35a15f543b57170369f4723714b8e896a6e79df324698c63973dfe5bab91f1c6c0e12d16f918900b0482c7e3bc17c125d78b1f191af1f2dae229f53f66be86d7d3455b496d3102f77b397c7454700423c5d762fdc8f2ddeb8b85a35b765dc5d6831b43e1a002bb6ba7533c4f7aac934fe60575f7de94891110d40a387fa43dc635f9dab2a5fb3fa2dcd86c6e522fe84c6c0f9a735d4d0684b62160c7b47b32054751da52267d66f1ab5c5a8f8db7dd11b50e49a24a50eb580a4e309c311bb52bc1b20541036542a0ecab23b0a3d692499dfbb10889dbb610a548c7f0ef78fdddd1a75348cc812c333163d6112ecaa4e7da1c97a4249c99b9050ae3690986f36532bb02914dd4cc3ee0988e491f8e1ed59d414ac09c62ec6160c75f513438f094d2f22286cd5817a8e43b613676680d330b47ba654a626029659e0a41ca2cd7294afdb1d552bfc79422fe954ff03ed343c84f0fc0de9ea798fed0e25bbcd5c3eb2784dee30f808e8e9b6a2fbd4a4d29108c355e58dd6f457b9af75aa7b1cc76162172ee5176dbb5139fda44a0341d2598106e3d34817494d38d52e69feeb9ef8fc3ead2fa7d372e2891be0f79f9f86e38e35a5cac63497267f31a783fad3b9c6c7ff9b385a527cf8e9985578a803c476e596a2afc0c40b031b9607ab7e16d18ac4fd8d040ad91cfaedf9b9d86923e38fed34be9c2af6376b3a529e5ec1ed437c0f2de456ee9a5b2ba54cf3106c5038c4c08f9b4a1e7c056fbc90e13f4bdebe5ec6738b65dbec6416d61b829808c1df07e514632b480c0b1f24fe715f928d270a1811ca99355801f8ea2b51f08b070962d399621e92684a5999f12d01c9e6d53c2e243858b5ffb2cdfcc70057dfe5f37f5f7807b8b2543beabfbae8458e26a6de724dc79c54b6fbed3831781f50c516d248932cbbd6bd3aec9d74521e9db2ac6026d931f0be2eeda1030dd18fa0a598301a06d3d59b01d1fd722c7f8d58faf94c0c8a13cc4d3ab543e32c3ecfe760aa9598145d6b6b667b9d8d39134b92c1556ad1b72867aa7ff33183602af09f1eb49c91827f3b88b075b7475b8a4f51ad3857e5e08128d91a03d44246cc2877bde14b6ea3928b659adc12fae5bf36953c71c9062069c1d26e4b9a1b9986fc0eb632391a04ead9882e49cc1eadd409951464b5c043464da69f6f2fc46e671c66cb05d722905cdfa224686d4683bcf579c50e19a52b42bacd9c38f135149d0371c4594725e5a24b3aafd02ddc220fb9c7d7092256a435a583fde2c3c89d675c1e294ee48e57c2006d7790545fd938e46ecb17fded2cb4d65604ec72a8d92c8f5a4973e4b4da4ceae81107f3854bd65726154977a12722b65a18f50b11eb040a22666bab7e8c5e0bbfddd58c0877c77d154e0d8559b261e3d414ea246baed897eb3bca7cc2810c0769441e30083d0576ecff3d5fc2a828600d6aae13bb2f35ecb6a4391596b04db7524119e1844c8024faf9469383e663396d1a02372862dc894bb2f130802f8b6747dc16a9020af03d4774353dff41b49754e13a721e9b5017656d7b804aea7dc65798e0a6780b825617b98d57662d60ce6cea97b5f79347c6c0d4ef03dae8ae619d44f5842e345a8a902c5d565b221697996288b4c1eab3d1ab82c3d1ef2e15b66c1e52e59755eea2b26ac36d39e29d786aae570cd2bfe7ea2f23ae5b3823f100eaf6bbc00ede09a8c268ac8477736a8bfd6b021deccc70518bfba677d8812078bb8df1f19ea74e33015dd3888b6dca35a4241440a703a9fed9cba35b7ac41afa8e6449305c29ae355e316a1c63da5b8daa6efd6f2fd4a05c101f492fb0e91019843f8ccfbefa20b70cb060c93837fcf832318cc0a8b9d9da6235c56b7f5ab1617fc2533e1ea28abd76700fef463c0c9955b52ec0e4e92250f318af8637a7e3777d86348032af8ecea1a76d64af0eb7b0e327b672fbb9b148823f721b31a8d5a7f70bd303d06357198604fc76eed80de18259e530f86d3c2a54a4f39a7ce3a6af70d4a9e1179b45bb8a63a9c69292f6dc4f80083ef81c16b02c221de5127e052e1c1b864e0d85248c8ceab6393a3e840c51d734e41a48cfd49f4c51f21500e8fb5d95963eb83a6303451955733a62444cdbeefafc8ce58504a541ebd84b90c56a4478a71f544764b8ad76d49d97e23d092cc78eecf257cf19b3af5f7b1f8b14a95fae2131c8cefae84ef52978e430c5656d929274ff14a4e6786b4616410af2c887d8149cab37f84a3af1096f5dc150a7f72a909be9c0814567fb29854faa41979d54b746d6629566832fc75d4249dc1e5f6ce8c10d3e008f956fad8f1514fcb55630679d637ce3eca2991866a4ef712b5c7f57aebad59e702e0c7ebb4363101361e48eb276bb3e72a5c27814c8d64bf7d47930b7188de7de32d15cba4452d40f51ea2eec21348d16306d0718c28e2f895f40b5699d2f5a7e320f9c681d8b83462eff2482dc44a14805511fa12c7c7fe438ce9e1d79cd18fab1746ec96fa1ce9fcc39094b0f45f06226eabb0682e3eab6eb590c34387ba1355408a40a8dd02637dbc4ce86909e0b454b3403e2dd17b88c4c98376abbc0932a77c86bf679dcc756b151d3e4bdd2f5100380555f11475f9ee784507470ea6f8ec1542f0e0d18c1913b22dcbfa6f589c2b50c50bd51987e5f90b82cfb47171e0d5f4f70329b39350ffa529e3988625cf5f7098ef4a549863412bac97c7df126683d319fa0f729a07a17a6a7c71998b2a383ee12c47d49f8f36c367a5fb8b4ca50ab67fdc3d7860183ef5ac3ea15f687edc0382a0b35342af2340e6162cd06d1c5a37b4e9e11a1ddc40ebe4acf5380a59e246d12f47db38002a2ad41de7db70770a620e97ca15d4d32d5d92bec51c81ea8b844040dc8bfc58acdf3a5197e36245277cc06249b47ad299569a4b96b6721d24100924f3a422a7e3430a0780ea7a2fcf5753c1f9a3349a243c6b754a0b309661fe0c21aa2fbb16f4652a0480a1b793f5f22811349c63e3daa6596c533b77c2f9284e38df9caef4e259fc063fe0213a81e10732c36a23298966cf26b2104ae86510c8adcc1aa941b9fe5f12bdd7c46c39709179fd3b53dc3319ca452246ec9108f6ace1c851550ef69887f11d2f9f3a3d529826b34b0d11e7df172d2d6492036bfcfef05d2d1f8a626a8567217b0d20d2b911f07e9a8afc4336839fd1e3610e5889bbca2130e6e933b0edca05ce45669280c43251fec61895a014a9da893456ba648e04da248070c92a2f7034ad8ce2e78dc82223c337163a422f88ca11fd46681ef76f78aa22a09ba5f1e204b35cba77cef3dc256aaff5d5748bc24657dc487e16c4f503545b0374a5c7fd61c8f7fd1b73e96b36187bd9dfa52af49dbc4154f9713cbc2bf5d9d10bf56a30f040f3ad1b1a39ebf7c89ea043e81c1b7301eddac85ab2e31deac59f3a9f6a90d1615c18ae90c694c1ad78456047f0217b443df72c3a606aa4fe470eb8132eb9b6e0d0dc4ef57e9c9d095c9137e8709142df8c7c3f822a14538ef2a9ecc42e5ea52b41b2116c79141bc3b2b38f4f0474243af794e18d5fb7af6cc85f98644f9931fdca5e2a6bf8c7b64a5ef8674e617bd37d26fa5a2c86d336807dca751e4134f769d6b55789751ea1ae993a69a50fa5cd41f0f394a9db506ba83edd294882a0a0f39495007e2562479a0871c65d650b4f898f8cc54f56602f823ddfa5248a7ee960652da1446aa70506ab25f34450c4a43ca793a83c52148adb0445433a183514073e41e70ac1a781a4194f718c3c6774f96c067657e144abc1f01c0fd760739303124de681abf2b2bd3bfb847ea1ac5cb235be42a937b823f988db57c3b5369c354811a94c65884ee2c2fbad93325e1d50fc79802241c18be312de15690c08f269f17b24477aaaa6690717fea16e8b2d6f2b5d7b02236e255d97d35093e91ae66f6e23e31ad79338b6173e5ce4f78f7379d970a94eae6ca3bca493e73d25e79480704e1106658d710dc8222c01910ab08153fd680697e11f869c5229000fcba05e327d34cd281b4c51939ecb926f08d31909f0df54244a5859c0c33304bf141e329f1f3c77dd0ce4fc0f22565ed3702cf0a8deb2e6cff75e600f6377bb1d9a4e02011136b910b14121232fa12b2e9aa080b6c34ce2cd7d3a0b3a21c4a8ba1a2b9c0a1f22f8523aba204df4758a738a55db89857e1f924e85e1e4dbd8c29dfc286f5e40f2e9d2f628c57f6c8a9c6470dd46d1e61ff375557904ac58aded4c04cfcf5d04cf2b603afbbbe8bbf56a8e20d0dc15a0b77ddc1e04d48069f25c23ec8e948c696610def49f0206e6d8a593de491c2c9568f511012bb19a806900e1f43095f374e0db6466af6d9798093fa78c5a6475819b48c2a719a17728a451f10e14a22ab3ea61e2cdaed4ff684a02b8f0ecfc66a9fad193e163f429fe8f1b4c4e508fb801834dd07acb650339b05561a70955f38c1e7657d87ada3b0de207968e16ddaf13aa003cec356b3a6c450a72705af04d66cdb46386fa16aa31e6bb44c660849009dcb8a682a57aa11c7e2b726a7db42770ddb8d1117f21cfecdcfb68a0dfcd43f985ecfb8b3901b77f9de68ba49cbd10ef5143913e14120dd44e99fab0fe2426b0c3d0cbd0b68f55f29448d9e7bb2a972780da1aecdc1b0d7c8c4fa6eec3cbefda75764e20941c91df437593e67e7403d2fccefab5452b2c6f6e93324caee2fc99fb5beb062f690b2a66af8557c70169ba2fcd22feb1d0771137a9e34b0249491141e7acc46519d5599119e732d48ff08a3f64cad57e6d00b4a948ccb08733055d068defe3e2eae06eba5ab4e50fcfd97fdc48ba80fef1469e84b3d436a1080935ec89d5dedb65ad9b111ac6ac22eb791470dec17a4490b95bffe949758289b6eda65bac431bb0a360e4f54bc40e2bafa208db26b3bd81a0a09eaf3f9363c54c10446285cdc8484d92d5e2cd6063806ad6aa498e5c3350e10d52c3d953bc51d1c9e3a15ce6aa80fb349d4cccff953cdbefdb1c72109eac261cb266a5852de0f93e5c09de61e8a0b7c63bf13000dc219069260a3441e35e5949186490e97caada3be30e885a50b88985fd2c41ce01b188ec91200bbfd9ef0742f8447f1ca6d31a7b4d38f970e27498bd1e63636b564964b6e58f85898afe7bf73fffbf2fe7ab6bc35e09baa2df28e6abf5d16df07650a12f02a023e12d805d736d2c5d150f74609792f6d6b52c65151157f8019885a5cac3b7cbadfc3f912faadecff18f863a0ec7ad6f15b3265b0d3aced115086720875c96b3e0622111201e7b62da8c24c820a93d318fabe9b3d7fb140cbc0a1f319583c8e0f3c6f605c71cfc4629048d0b4b2e10ccead41a3657df0f49281bf87577ed7d3ec031a9370ae14738f8ee6264011f9408acfe5e1c30a8348d1e648907e2d168c071afd39799bdb16262b3ecb24400ca2964184535edd46500d8fff5ff3b975ab03451fc7c1dce11cabc147bdce4214446c49f2bac43ff6d48f4c1124e118b42bca38739c343ee76460fac44e23b6f9c5067e7b6d037461ac94d1f4326242763428c84e100c3284e492731bb6920082e5bf0811ebcd00ca61edfd8070e2e42198531e9e8cbed98d287d734c134e3917e01aa79c6cf73cae3b7483987c6d2f6e421d4e2d7abd350657b6c7f92b64efcec64af24e5fc8e93b18b0749e4a64e4a91a31a5c46ad03f509a188733a02a4613411036ac2bc151dfd679dd0406477c8d2a81ae69741e41a2e8d252a9a561dcc7e531e1579e7c9a6a996c198e6827fbb9fa07aed26b483e1566ff5a2a22779a2ee1144794a3f5c7317292baaeecc9b5c6217a4037db82cb5296ef7b97cb4269ead9e7aae78e242a035ca019841b50c93daa58db0d0f14fc4ba660e031692dac97acbf4361a6fc5a56d53cd9d51bfc0409e45882452e2c74b3cdc25a6fbaaed3b0676f3357c464f294e48195d1d20380dd5569c953ba52895804ad8538a151b04772d977257287bf7e4f57173109e72ea9e4cb083ae72ee7fd8f4e3dae46d26e35e70b4b83ae4780d603993c09f85455e64dbffb4620de70b27e5e8403ae66649f7efb2bc21e46c8ed63664f8cf56fae1dcd4eafd88d3e91b034252a7796003778c2b62e03825ffbccc0d269403f7c72cf76530c76c7775da9ebf8b214b35445a147cc2a2a01a71645cd9d3fec5b0875d8ea063fb10146c947e6727aac8cf9c983f355292ef6ae765715843593c2744b7d0d1a4728f030f27b1f936028bc1819dee086ee869d1b5748152baf96f2837b28b9e29d6162430fe41ee8228020df3190b9032e9756ca3b71ffa000325d8e313ee2bb7658e8f7fadc07e7d9c2015bba44de6816902f4f857a86c3fa73f4c4e0a1deb8f77167e9e0ebd742b0ee4dbd18d153f12169989176f6d0e32d108af0b984b5c86c649d22761c91e95c75a692c4bc73fe6dc131212a4930661cad05817999111deb07f804a947c323836564a7d8e5a546504f2f0c2dfa84778bb8da76fe668a82941dff9c70b503bd911146e2e89d4515ea52093f68d5aebb85da56dfddf0288ae2a11bd9e3525603fcb1441c78c4db3e5cafde4e26d9a40b4dbce895a3389bb1963213d321011fd1455e08b33b62035c501e46180bcef5ed6aeed36f9b890d00d9300929f92d8a47e8561e929120af48b332eff6c8b13b4cdf83bd6473d8a8233d316a82300c688ad373ece653f55195c234e12f6993207b180f37b49245909c6f4d294839b3dc5d22ca66034699cc3a4eaf9417071060e63ff863f4e3b059862bb7cf82739c763e3ecaec5425106c7f2805d1a6e70772096ecb306fd9211d2601777193c6c56a4c21e687cbdfd9f213cf01a3da84d933fe67c79b71358b1f9d4d81ae9621a114dcb46afc0b1a49bae8f23908343bf7c6c613aab21cffe91f0e8b288b916b970bfd3923b3a06d9f654e26b07b066c304756a2de1d8501a3ee5306fd616ca7a17ba2ece83de9743ef1fd52e1ab6a6838904af8c47afba88c0820f018e1385903b3ceab9dd33c79c066e86b9665568be2cb2db76059dc99ce016e403bd43f1800073b95cd9e2cb936846e080fb4dba52dfb62020a9269a3b84d610fb22aed285098fea3968fbfbbbf0df879f346fb4ad3e7de8e7c28abebc71a5bd3193382ef1708b856129b767d559589db2996eecc2295b861f37692addb3d41cf576f388be87b23d1a793c75cd68f2d00126fd7cc4592b14b3864c60d869c18174603236926f82fb9059ba9de017e8946b04d1521bcf3b1419606c49aee3421f3a24c8cc1d2daf9cd33b956291231df68bcec04543446260d41f474d76e5085f6595868c8612d7b980586d5b8c286bc3b952b62a58964c0bd018ff384751d67f4194616cf03f7aca84c65c0eff574607c1cfba122614cd996cd05641b2"; diff --git a/benches/bench/gen_data.py b/benches/bench/gen_data.py new file mode 100755 index 0000000..84ce0b8 --- /dev/null +++ b/benches/bench/gen_data.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import random + +enc = [] +dec = [] +for i in [32, 256, 2048, 16384]: + enc_data = bytearray([random.randint(0, 255) for _ in range(i)]).hex() + enc.append(f'pub const ENC_{i}: &[u8; {i}] = &hex!("{enc_data}");') + + dec_data = bytearray([random.randint(0, 255) for _ in range(i // 2)]).hex() + dec.append(f'pub const DEC_{i}: &str = "{dec_data}";') + +enc = f"\n".join(enc) +dec = f"\n".join(dec) +print( + f"""\ +// @generated by gen_data.py, do not modify manually +use hex_literal::hex; + +{enc} + +{dec}\ +""" +) diff --git a/benches/bench/main.rs b/benches/bench/main.rs new file mode 100644 index 0000000..b1e198c --- /dev/null +++ b/benches/bench/main.rs @@ -0,0 +1,202 @@ +#![feature(test)] + +extern crate test; + +#[rustfmt::skip] +mod data; + +use std::fmt; +use std::io::Write; +use test::{black_box, Bencher}; + +struct HexBufferFormat(&'static [u8; N]); +impl fmt::Display for HexBufferFormat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut buffer = const_hex::Buffer::::new(); + f.write_str(buffer.format(self.0)) + } +} + +struct StdFormat(&'static [u8; N]); +impl fmt::Display for StdFormat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for &byte in self.0 { + write!(f, "{byte:02x}")?; + } + Ok(()) + } +} + +macro_rules! benches { + ($($name:ident($enc:expr, $dec:expr))*) => { + #[cfg(feature = "alloc")] + mod decode { + use super::*; + + mod const_hex { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + b.iter(|| { + ::const_hex::decode(black_box($dec)) + }); + } + )* + } + + mod hex { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + b.iter(|| { + ::hex::decode(black_box($dec)) + }); + } + )* + } + } + + mod decode_to_slice { + use super::*; + + mod const_hex { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + let buf = &mut [0; $dec.len() / 2]; + + b.iter(|| { + let res = ::const_hex::decode_to_slice(black_box($dec), black_box(buf)); + black_box(res.unwrap()); + }); + } + )* + } + + mod hex { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + let buf = &mut [0; $dec.len() / 2]; + + b.iter(|| { + ::hex::decode_to_slice(black_box($dec), black_box(buf)) + }); + } + )* + } + } + + #[cfg(feature = "alloc")] + mod encode { + use super::*; + + mod const_hex { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + b.iter(|| { + ::const_hex::encode(black_box($enc)) + }); + } + )* + } + + mod hex { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + b.iter(|| { + ::hex::encode(black_box($enc)) + }); + } + )* + } + } + + mod encode_to_slice { + use super::*; + + mod const_hex { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + let buf = &mut [0; $enc.len() * 2]; + b.iter(|| { + ::const_hex::encode_to_slice(black_box($enc), black_box(buf)) + }); + } + )* + } + + mod hex { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + let buf = &mut [0; $enc.len() * 2]; + b.iter(|| { + ::hex::encode_to_slice(black_box($enc), black_box(buf)) + }); + } + )* + } + } + + mod format { + use super::*; + + mod const_hex { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + let mut buf = Vec::with_capacity($enc.len() * 2); + b.iter(|| { + buf.clear(); + write!(&mut buf, "{}", HexBufferFormat(black_box($enc))) + }); + } + )* + } + + mod std { + use super::*; + + $( + #[bench] + fn $name(b: &mut Bencher) { + let mut buf = Vec::with_capacity($enc.len() * 2); + b.iter(|| { + buf.clear(); + write!(&mut buf, "{}", StdFormat(black_box($enc))) + }); + } + )* + } + } + } +} + +benches! { + bench1_32(data::ENC_32, data::DEC_32) + bench2_256(data::ENC_256, data::DEC_256) + bench3_2048(data::ENC_2048, data::DEC_2048) + bench4_16384(data::ENC_16384, data::DEC_16384) +}