Skip to content

Commit

Permalink
perf: improve simnet datastore data struct
Browse files Browse the repository at this point in the history
  • Loading branch information
hugocaillard committed Nov 28, 2024
1 parent 39f6498 commit 8de8a16
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 37 deletions.
60 changes: 59 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ web-sys = { version = "0.3" }
chainhook-sdk = { git = "https://github.com/hirosystems/chainhook.git" }
chainhook-types = { git = "https://github.com/hirosystems/chainhook.git" }
stacks-codec = { path = "./components/stacks-codec" }

# [patch.'https://github.com/stacks-network/stacks-core.git']
# clarity = { path = "../stacks-core/clarity" }
# stacks-common = { path = "../stacks-core/stacks-common" }
# stackslib = { path = "../stacks-core/stackslib" }
5 changes: 5 additions & 0 deletions components/clarity-repl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ reqwest = { workspace = true }

[dev-dependencies]
test-case = "*"
divan = "0.1"

[lib]
name = "clarity_repl"
Expand All @@ -65,6 +66,10 @@ path = "src/lib.rs"
name = "clarity-repl"
path = "src/bin.rs"

[[bench]]
name = "simnet"
harness = false

[features]
default = ["cli", "dap"]
sdk = [
Expand Down
163 changes: 163 additions & 0 deletions components/clarity-repl/benches/simnet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
use std::hint::black_box;

use clarity::{
types::StacksEpochId,
vm::{
types::QualifiedContractIdentifier, EvaluationResult, ExecutionResult, SymbolicExpression,
Value as ClarityValue,
},
};
use clarity_repl::repl::{
ClarityCodeSource, ClarityContract, ContractDeployer, Session, SessionSettings,
DEFAULT_CLARITY_VERSION, DEFAULT_EPOCH,
};
use divan::Bencher;

fn init_session() -> Session {
let mut session = Session::new(SessionSettings::default());
session.update_epoch(StacksEpochId::Epoch30);
session.advance_burn_chain_tip(1);
assert_eq!(session.interpreter.get_block_height(), 2);

let src = [
"(define-data-var buff-data (buff 32) 0x00)",
"(define-map history uint (buff 32))",
"(define-read-only (noop-ro (i uint) (d (buff 32)))",
" (ok true)",
")",
"(define-public (noop-pub (i uint) (d (buff 32)))",
" (ok true)",
")",
"(define-public (save (i uint) (d (buff 32)))",
" (begin",
" (map-insert history i d)",
" (ok (var-set buff-data d))",
" )",
")",
]
.join("\n");

let contract = ClarityContract {
code_source: ClarityCodeSource::ContractInMemory(src.to_string()),
name: "contract".into(),
deployer: ContractDeployer::DefaultDeployer,
clarity_version: DEFAULT_CLARITY_VERSION,
epoch: DEFAULT_EPOCH,
};

let _ = session.deploy_contract(&contract, false, None);
session.advance_burn_chain_tip(1);

assert_eq!(session.interpreter.get_block_height(), 3);
session
}

fn call_fn(
session: &mut Session,
func: &str,
args: &[ClarityValue],
advance_chain: bool,
) -> ClarityValue {
let ExecutionResult { result, .. } = session
.call_contract_fn(
"contract",
func,
&args
.iter()
.map(|v: &ClarityValue| SymbolicExpression::atom_value(v.clone()))
.collect::<Vec<SymbolicExpression>>(),
"ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM",
false,
false,
)
.unwrap();

let v = match &result {
EvaluationResult::Snippet(r) => r.result.clone(),
EvaluationResult::Contract(_contract) => {
unreachable!();
}
};
if advance_chain {
let _ = session.advance_stacks_chain_tip(1);
}
v
}

fn int_to_buff(i: u32) -> ClarityValue {
let str = i.to_string();
let buff = str.bytes().collect::<Vec<u8>>();
ClarityValue::buff_from(buff).unwrap()
}

#[divan::bench(sample_count = 10000)]
fn simnet_noop_read_only(bencher: Bencher) {
let mut session = init_session();
let initial_block_height = session.interpreter.get_block_height();
let mut i: u32 = 0;

bencher.bench_local(|| {
let args = [ClarityValue::UInt(black_box(i.into())), int_to_buff(i)];
let result = call_fn(black_box(&mut session), "noop-ro", &args, false);
assert_eq!(
black_box(initial_block_height),
session.interpreter.get_block_height()
);
assert_eq!(result, ClarityValue::okay_true());

i += 1;
});
}

#[divan::bench(sample_count = 10000)]
fn simnet_noop_public(bencher: Bencher) {
let mut session = init_session();
let initial_block_height = session.interpreter.get_block_height();
let mut i: u32 = 0;

bencher.bench_local(|| {
let args = [ClarityValue::UInt(black_box(i).into()), int_to_buff(i)];
let result = call_fn(black_box(&mut session), "noop-pub", &args, true);

assert_eq!(
black_box(initial_block_height + i + 1),
session.interpreter.get_block_height()
);
assert_eq!(result, ClarityValue::okay_true());
i += 1;
});
}

#[divan::bench(sample_count = 10000)]
fn simnet_save(bencher: Bencher) {
let mut session = init_session();
let initial_block_height = session.interpreter.get_block_height();
let mut i: u32 = 0;

bencher.bench_local(|| {
let args = [ClarityValue::UInt(black_box(i).into()), int_to_buff(i)];
let result = call_fn(black_box(&mut session), "save", &args, true);

assert_eq!(
black_box(initial_block_height + i + 1),
session.interpreter.get_block_height()
);
assert_eq!(result, ClarityValue::okay_true());
i += 1;
});

let contract_id =
QualifiedContractIdentifier::parse("ST000000000000000000002AMW42H.contract").unwrap();
let contract_data = session
.interpreter
.get_data_var(&contract_id, "buff-data")
.unwrap();

let expected = format!("0x{}", int_to_buff(i - 1).serialize_to_hex().unwrap());
assert_eq!(contract_data, expected);
}

fn main() {
// simnet_benchmark();
divan::main();
}
Loading

0 comments on commit 8de8a16

Please sign in to comment.