From e80cff55f56ee5b33c316fa86896e0aa4c3b292e Mon Sep 17 00:00:00 2001 From: notV4l Date: Wed, 24 Apr 2024 19:46:40 +0200 Subject: [PATCH] dojo-core: update gas logs --- crates/dojo-core/src/benchmarks.cairo | 195 +++++++++++--------------- crates/dojo-core/src/test_utils.cairo | 54 +++---- crates/dojo-core/src/world_test.cairo | 26 ++-- 3 files changed, 118 insertions(+), 157 deletions(-) diff --git a/crates/dojo-core/src/benchmarks.cairo b/crates/dojo-core/src/benchmarks.cairo index 03c5ca2bab..e9a3d89a5d 100644 --- a/crates/dojo-core/src/benchmarks.cairo +++ b/crates/dojo-core/src/benchmarks.cairo @@ -10,15 +10,14 @@ use dojo::database; use dojo::database::storage; use dojo::model::Model; use dojo::world_test::Foo; -use dojo::test_utils::end; +use dojo::test_utils::GasCounterImpl; #[test] #[available_gas(1000000000)] fn bench_reference_offset() { - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); - end(gas, 'bench empty'); + let gas = GasCounterImpl::start(); + gas.end("bench empty"); } #[test] @@ -26,15 +25,13 @@ fn bench_reference_offset() { fn bench_storage_single() { let keys = array!['database_test', '42'].span(); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); storage::set(0, keys, 420); - end(gas, 'storage set'); + gas.end("storage set"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let res = storage::get(0, keys); - end(gas, 'storage get'); + gas.end("storage get"); assert(res == 420, 'values differ'); } @@ -46,15 +43,13 @@ fn bench_storage_many() { let values = array![1, 2].span(); let layout = array![251, 251].span(); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); storage::set_many(0, keys, values, layout).unwrap(); - end(gas, 'storage set mny'); + gas.end("storage set_many"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let res = storage::get_many(0, keys, layout).unwrap(); - end(gas, 'storage get mny'); + gas.end("storage get_many"); assert(res.len() == 2, 'wrong number of values'); assert(*res.at(0) == *values.at(0), 'value not set'); @@ -64,22 +59,19 @@ fn bench_storage_many() { #[test] #[available_gas(1000000000)] fn bench_native_storage() { - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let keys = array![0x1337].span(); let base = starknet::storage_base_address_from_felt252(poseidon_hash_span(keys)); let address = starknet::storage_address_from_base(base); - end(gas, 'native prep'); + gas.end("native prep"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); starknet::storage_write_syscall(0, address, 42).unwrap_syscall(); - end(gas, 'native write'); + gas.end("native write"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let value = starknet::storage_read_syscall(0, address).unwrap_syscall(); - end(gas, 'native read'); + gas.end("native read"); assert(value == 42, 'read invalid'); } @@ -87,22 +79,19 @@ fn bench_native_storage() { #[test] #[available_gas(1000000000)] fn bench_native_storage_offset() { - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let keys = array![0x1337].span(); let base = starknet::storage_base_address_from_felt252(poseidon_hash_span(keys)); let address = starknet::storage_address_from_base_and_offset(base, 42); - end(gas, 'native prep of'); + gas.end("native prep of"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); starknet::storage_write_syscall(0, address, 42).unwrap_syscall(); - end(gas, 'native writ of'); + gas.end("native writ of"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let value = starknet::storage_read_syscall(0, address).unwrap_syscall(); - end(gas, 'native read of'); + gas.end("native read of"); assert(value == 42, 'read invalid'); } @@ -129,15 +118,13 @@ fn bench_database_array() { i += 1; }; - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); database::set('table', 'key', values.span(), layout.span()); - end(gas, 'db set arr'); + gas.end( "db set arr"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let res = database::get('table', 'key', layout.span()); - end(gas, 'db get arr'); + gas.end("db get arr"); let mut i = 0; loop { @@ -155,27 +142,20 @@ fn bench_database_array() { fn bench_simple_struct() { let caller = starknet::contract_address_const::<0x42>(); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); - let mut foo = Foo { - caller, - a: 0x123456789abcdef, - b: 0x123456789abcdef, - }; - end(gas, 'foo init'); + let gas = GasCounterImpl::start(); + let mut foo = Foo { caller, a: 0x123456789abcdef, b: 0x123456789abcdef, }; + gas.end("foo init"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let mut serialized = ArrayTrait::new(); serde::Serde::serialize(@foo.a, ref serialized); serde::Serde::serialize(@foo.b, ref serialized); let serialized = array::ArrayTrait::span(@serialized); - end(gas, 'foo serialize'); + gas.end("foo serialize"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let values: Span = foo.values(); - end(gas, 'foo values'); + gas.end("foo values"); assert(serialized.len() == 2, 'serialized wrong length'); assert(values.len() == 2, 'value wrong length'); @@ -199,8 +179,7 @@ struct PositionWithQuaterions { #[test] #[available_gas(1000000000)] fn test_struct_with_many_fields() { - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let mut pos = PositionWithQuaterions { id: 0x123456789abcdef, @@ -212,10 +191,9 @@ fn test_struct_with_many_fields() { c: 0x123456789abcdef, d: 0x123456789abcdef, }; - end(gas, 'pos init'); + gas.end( "pos init"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let mut serialized = ArrayTrait::new(); serde::Serde::serialize(@pos.x, ref serialized); serde::Serde::serialize(@pos.y, ref serialized); @@ -225,12 +203,11 @@ fn test_struct_with_many_fields() { serde::Serde::serialize(@pos.c, ref serialized); serde::Serde::serialize(@pos.d, ref serialized); let serialized = array::ArrayTrait::span(@serialized); - end(gas, 'pos serialize'); + gas.end("pos serialize"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let values: Span = pos.values(); - end(gas, 'pos values'); + gas.end("pos values"); assert(serialized.len() == values.len(), 'serialized not equal'); let mut idx = 0; @@ -242,15 +219,13 @@ fn test_struct_with_many_fields() { idx += 1; }; - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); database::set('positions', '42', pos.values(), pos.layout()); - end(gas, 'pos db set'); + gas.end("pos db set"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); database::get('positions', '42', pos.layout()); - end(gas, 'pos db get'); + gas.end("pos db get"); } @@ -273,34 +248,27 @@ struct Case { #[available_gas(1000000000)] fn bench_nested_struct() { let caller = starknet::contract_address_const::<0x42>(); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); - + + let gas = GasCounterImpl::start(); let mut case = Case { - owner: caller, - sword: Sword { - swordsmith: caller, - damage: 0x12345678, - }, - material: 'wooden', + owner: caller, sword: Sword { swordsmith: caller, damage: 0x12345678, }, material: 'wooden', }; - end(gas, 'case init'); + gas.end( "case init"); + + // ???? let _gas = testing::get_available_gas(); gas::withdraw_gas().unwrap(); - - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let mut serialized = ArrayTrait::new(); serde::Serde::serialize(@case.sword, ref serialized); serde::Serde::serialize(@case.material, ref serialized); let serialized = array::ArrayTrait::span(@serialized); - end(gas, 'case serialize'); + gas.end( "case serialize"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let values: Span = case.values(); - end(gas, 'case values'); + gas.end("case values"); assert(serialized.len() == values.len(), 'serialized not equal'); let mut idx = 0; @@ -312,15 +280,13 @@ fn bench_nested_struct() { idx += 1; }; - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); database::set('cases', '42', values, case.layout()); - end(gas, 'case db set'); + gas.end( "case db set"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); database::get('cases', '42', case.layout()); - end(gas, 'case db get'); + gas.end( "case db get"); } #[derive(Model, Copy, Drop, Serde)] @@ -366,8 +332,7 @@ enum Weapon { #[test] #[available_gas(1000000000)] fn bench_complex_struct() { - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let char = Character { caller: starknet::contract_address_const::<0x42>(), @@ -391,22 +356,21 @@ fn bench_complex_struct() { finished: true, romances: 0x1234, }, - weapon: Weapon::DualWield(( - Sword { - swordsmith: starknet::contract_address_const::<0x69>(), - damage: 0x12345678, - }, - Sword { - swordsmith: starknet::contract_address_const::<0x69>(), - damage: 0x12345678, - } - )), + weapon: Weapon::DualWield( + ( + Sword { + swordsmith: starknet::contract_address_const::<0x69>(), damage: 0x12345678, + }, + Sword { + swordsmith: starknet::contract_address_const::<0x69>(), damage: 0x12345678, + } + ) + ), gold: 0x12345678, }; - end(gas, 'chars init'); + gas.end("chars init"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let mut serialized = ArrayTrait::new(); serde::Serde::serialize(@char.heigth, ref serialized); serde::Serde::serialize(@char.abilities, ref serialized); @@ -414,12 +378,11 @@ fn bench_complex_struct() { serde::Serde::serialize(@char.weapon, ref serialized); serde::Serde::serialize(@char.gold, ref serialized); let serialized = array::ArrayTrait::span(@serialized); - end(gas, 'chars serialize'); + gas.end("chars serialize"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let values: Span = char.values(); - end(gas, 'chars values'); + gas.end("chars values"); assert(serialized.len() == values.len(), 'serialized not equal'); @@ -432,13 +395,11 @@ fn bench_complex_struct() { idx += 1; }; - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); database::set('chars', '42', char.values(), char.layout()); - end(gas, 'chars db set'); + gas.end("chars db set"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); database::get('chars', '42', char.layout()); - end(gas, 'chars db get'); + gas.end("chars db get"); } diff --git a/crates/dojo-core/src/test_utils.cairo b/crates/dojo-core/src/test_utils.cairo index 6a83bcdda7..3cffffa851 100644 --- a/crates/dojo-core/src/test_utils.cairo +++ b/crates/dojo-core/src/test_utils.cairo @@ -68,34 +68,34 @@ fn spawn_test_world(models: Array) -> IWorldDispatcher { } -const GAS_OFFSET: felt252 = 0x1_000000_000000_000000_000000_000000; // 15 bajtów +#[derive(Drop)] +struct GasCounter { + start: u128, +} -/// Measures gas used after previous measurement and prints it -/// -/// # Arguments -/// -/// * `start` - gas before measurement -/// * `name` - name of test, at most 15 bytes, will be padded with spaces -fn end(start: u128, name: felt252) { - let gas_after = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); - let mut name: u256 = name.into(); +#[generate_trait] +impl GasCounterImpl of GasCounterTrait { + fn start() -> GasCounter { + let start = testing::get_available_gas(); + gas::withdraw_gas().unwrap(); + GasCounter { start } + } - // overwriting zeros with spaces - let mut char = 0; - loop { - if char == 15 { - break; - } - // if given byte is zero - if shl(0xff, 8 * char) & name == 0 { - name = name | shl(0x20, 8 * char); // set space - } - char += 1; - }; + fn end(self: GasCounter, name: ByteArray) { + let end = testing::get_available_gas(); + let gas_used = self.start - end; + + println!("# GAS # {}: {}", GasCounterImpl::pad_start(name, 18), gas_used); + gas::withdraw_gas().unwrap(); + } - let name: felt252 = (name % GAS_OFFSET.into()).try_into().unwrap(); - // Q?: What's this 1070 value that needed to be adjusted? - let used_gas = (start - gas_after - 1070).into() * GAS_OFFSET; - (used_gas + name).print(); + fn pad_start(str: ByteArray, len: u32) -> ByteArray{ + let mut missing: ByteArray = ""; + let missing_len = if str.len() >= len { 0 } else { len - str.len()}; + + while missing.len() < missing_len { + missing.append(@"."); + }; + missing + str + } } diff --git a/crates/dojo-core/src/world_test.cairo b/crates/dojo-core/src/world_test.cairo index ae6ef28d56..7aa4c8664e 100644 --- a/crates/dojo-core/src/world_test.cairo +++ b/crates/dojo-core/src/world_test.cairo @@ -14,7 +14,8 @@ use dojo::world::{ }; use dojo::database::introspect::Introspect; use dojo::test_utils::{spawn_test_world, deploy_with_world_address}; -use dojo::benchmarks::{Character, end}; +use dojo::benchmarks::{Character, GasCounterImpl}; + #[derive(Model, Copy, Drop, Serde)] struct Foo { @@ -477,15 +478,14 @@ fn bench_execute() { let alice = starknet::contract_address_const::<0x1337>(); starknet::testing::set_contract_address(alice); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); + bar_contract.set_foo(1337, 1337); - end(gas, 'foo set call'); + gas.end( "foo set call"); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); let data = get!(world, alice, Foo); - end(gas, 'foo get macro'); + gas.end("foo get macro"); assert(data.a == 1337, 'data not stored'); } @@ -501,15 +501,15 @@ fn bench_execute_complex() { let alice = starknet::contract_address_const::<0x1337>(); starknet::testing::set_contract_address(alice); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); + let gas = GasCounterImpl::start(); + bar_contract.set_char(1337, 1337); - end(gas, 'char set call'); + gas.end( "char set call"); + + let gas = GasCounterImpl::start(); - let gas = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); let data = get!(world, alice, Character); - end(gas, 'char get macro'); + gas.end("char get macro"); assert(data.heigth == 1337, 'data not stored'); }