Skip to content

Instantly share code, notes, and snippets.

@1500256797
Forked from buffalojoec/bytemuck_bench.rs
Created May 21, 2025 06:45
Show Gist options
  • Save 1500256797/058b40ff351e5b4f96d2e8a7db64b53a to your computer and use it in GitHub Desktop.
Save 1500256797/058b40ff351e5b4f96d2e8a7db64b53a to your computer and use it in GitHub Desktop.
Interpreting account data with bytemuck is cheap
use {
bytemuck::{Pod, Zeroable},
pinocchio::{
account_info::AccountInfo, program_entrypoint,
pubkey::Pubkey, ProgramResult, program_error::ProgramError,
},
};
#[derive(Clone, Copy, Pod, Zeroable)]
#[repr(C)]
struct SmallData {
payload: [Pubkey; 2],
}
#[derive(Clone, Copy, Pod, Zeroable)]
#[repr(C)]
struct MediumData {
payload: [Pubkey; 16],
}
#[derive(Clone, Copy, Pod, Zeroable)]
#[repr(C)]
struct LargeData {
payload: [Pubkey; 32],
}
program_entrypoint!(process_instruction);
#[inline(always)]
fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
input: &[u8],
) -> ProgramResult {
let info = &accounts[0];
match input.first() {
Some(&0) => {
// No-op (base)
()
}
Some(&1) => {
// Account data borrow
let _ = info.try_borrow_data()?;
}
Some(&2) => {
// bytemuck cast small
let data = info.try_borrow_data()?;
let _ = bytemuck::from_bytes::<SmallData>(&data);
}
Some(&3) => {
// bytemuck cast medium
let data = info.try_borrow_data()?;
let _ = bytemuck::from_bytes::<MediumData>(&data);
}
Some(&4) => {
// bytemuck cast large
let data = info.try_borrow_data()?;
let _ = bytemuck::from_bytes::<LargeData>(&data);
}
_ => Err(ProgramError::InvalidInstructionData)?,
}
Ok(())
}
#[cfg(all(test, feature = "test-sbf"))]
mod tests {
use {
super::*,
mollusk_svm::{result::Check, Mollusk},
solana_account::Account,
solana_instruction::{AccountMeta, Instruction},
solana_pubkey::Pubkey,
};
fn run_test(
ix_dscr: u8,
acct_data: &[u8],
cus: u64,
) {
let program_id = Pubkey::new_unique();
let key = Pubkey::new_unique();
Mollusk::new(&program_id, "tests").process_and_validate_instruction(
&Instruction::new_with_bytes(program_id, &[ix_dscr], vec![AccountMeta::new(key, false)]),
&[(key, Account { data: acct_data.to_vec(), ..Default::default() })],
&[Check::success(), Check::compute_units(cus)],
);
}
#[test]
fn test_base() {
run_test(
0,
&[],
/* CUs: */ 39,
);
}
#[test]
fn test_account_borrow() {
run_test(
1,
&[],
/* CUs: */ 49,
);
}
#[test]
fn test_bytemuck_small() {
run_test(
2,
bytemuck::bytes_of(&SmallData {
payload: [[4; 32]; 2],
}),
/* CUs: */ 55,
);
}
#[test]
fn test_bytemuck_medium() {
run_test(
3,
bytemuck::bytes_of(&MediumData {
payload: [[4; 32]; 16],
}),
/* CUs: */ 56,
);
}
#[test]
fn test_bytemuck_large() {
run_test(
4,
bytemuck::bytes_of(&LargeData {
payload: [[4; 32]; 32],
}),
/* CUs: */ 56,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment