process_compute_budget_instructions.rs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. use {
  2. agave_feature_set::FeatureSet,
  3. criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput},
  4. solana_compute_budget_instruction::instructions_processor::process_compute_budget_instructions,
  5. solana_compute_budget_interface::ComputeBudgetInstruction,
  6. solana_instruction::Instruction,
  7. solana_keypair::Keypair,
  8. solana_message::Message,
  9. solana_pubkey::Pubkey,
  10. solana_signer::Signer,
  11. solana_svm_transaction::svm_message::SVMStaticMessage,
  12. solana_system_interface::instruction::transfer,
  13. solana_transaction::{sanitized::SanitizedTransaction, Transaction},
  14. };
  15. const NUM_TRANSACTIONS_PER_ITER: usize = 1024;
  16. const DUMMY_PROGRAM_ID: &str = "dummmy1111111111111111111111111111111111111";
  17. fn build_sanitized_transaction(
  18. payer_keypair: &Keypair,
  19. instructions: &[Instruction],
  20. ) -> SanitizedTransaction {
  21. SanitizedTransaction::from_transaction_for_tests(Transaction::new_unsigned(Message::new(
  22. instructions,
  23. Some(&payer_keypair.pubkey()),
  24. )))
  25. }
  26. fn bench_process_compute_budget_instructions_empty(c: &mut Criterion) {
  27. for feature_set in [FeatureSet::default(), FeatureSet::all_enabled()] {
  28. c.benchmark_group("bench_process_compute_budget_instructions_empty")
  29. .throughput(Throughput::Elements(NUM_TRANSACTIONS_PER_ITER as u64))
  30. .bench_function("0 instructions", |bencher| {
  31. let tx = build_sanitized_transaction(&Keypair::new(), &[]);
  32. bencher.iter(|| {
  33. (0..NUM_TRANSACTIONS_PER_ITER).for_each(|_| {
  34. assert!(process_compute_budget_instructions(
  35. black_box(SVMStaticMessage::program_instructions_iter(&tx)),
  36. black_box(&feature_set),
  37. )
  38. .is_ok())
  39. })
  40. });
  41. });
  42. }
  43. }
  44. fn bench_process_compute_budget_instructions_no_builtins(c: &mut Criterion) {
  45. let num_instructions = 4;
  46. for feature_set in [FeatureSet::default(), FeatureSet::all_enabled()] {
  47. c.benchmark_group("bench_process_compute_budget_instructions_no_builtins")
  48. .throughput(Throughput::Elements(NUM_TRANSACTIONS_PER_ITER as u64))
  49. .bench_function(
  50. format!("{num_instructions} dummy Instructions"),
  51. |bencher| {
  52. let ixs: Vec<_> = (0..num_instructions)
  53. .map(|_| {
  54. Instruction::new_with_bincode(
  55. DUMMY_PROGRAM_ID.parse().unwrap(),
  56. &(),
  57. vec![],
  58. )
  59. })
  60. .collect();
  61. let tx = build_sanitized_transaction(&Keypair::new(), &ixs);
  62. bencher.iter(|| {
  63. (0..NUM_TRANSACTIONS_PER_ITER).for_each(|_| {
  64. assert!(process_compute_budget_instructions(
  65. black_box(SVMStaticMessage::program_instructions_iter(&tx)),
  66. black_box(&feature_set),
  67. )
  68. .is_ok())
  69. })
  70. });
  71. },
  72. );
  73. }
  74. }
  75. fn bench_process_compute_budget_instructions_compute_budgets(c: &mut Criterion) {
  76. for feature_set in [FeatureSet::default(), FeatureSet::all_enabled()] {
  77. c.benchmark_group("bench_process_compute_budget_instructions_compute_budgets")
  78. .throughput(Throughput::Elements(NUM_TRANSACTIONS_PER_ITER as u64))
  79. .bench_function("4 compute-budget instructions", |bencher| {
  80. let ixs = vec![
  81. ComputeBudgetInstruction::request_heap_frame(40 * 1024),
  82. ComputeBudgetInstruction::set_compute_unit_limit(u32::MAX),
  83. ComputeBudgetInstruction::set_compute_unit_price(u64::MAX),
  84. ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(u32::MAX),
  85. ];
  86. let tx = build_sanitized_transaction(&Keypair::new(), &ixs);
  87. bencher.iter(|| {
  88. (0..NUM_TRANSACTIONS_PER_ITER).for_each(|_| {
  89. assert!(process_compute_budget_instructions(
  90. black_box(SVMStaticMessage::program_instructions_iter(&tx)),
  91. black_box(&feature_set),
  92. )
  93. .is_ok())
  94. })
  95. });
  96. });
  97. }
  98. }
  99. fn bench_process_compute_budget_instructions_builtins(c: &mut Criterion) {
  100. for feature_set in [FeatureSet::default(), FeatureSet::all_enabled()] {
  101. c.benchmark_group("bench_process_compute_budget_instructions_builtins")
  102. .throughput(Throughput::Elements(NUM_TRANSACTIONS_PER_ITER as u64))
  103. .bench_function("4 dummy builtins", |bencher| {
  104. let ixs = vec![
  105. Instruction::new_with_bincode(solana_sdk_ids::bpf_loader::id(), &(), vec![]),
  106. Instruction::new_with_bincode(
  107. solana_sdk_ids::secp256k1_program::id(),
  108. &(),
  109. vec![],
  110. ),
  111. Instruction::new_with_bincode(
  112. solana_sdk_ids::address_lookup_table::id(),
  113. &(),
  114. vec![],
  115. ),
  116. Instruction::new_with_bincode(solana_sdk_ids::loader_v4::id(), &(), vec![]),
  117. ];
  118. let tx = build_sanitized_transaction(&Keypair::new(), &ixs);
  119. bencher.iter(|| {
  120. (0..NUM_TRANSACTIONS_PER_ITER).for_each(|_| {
  121. assert!(process_compute_budget_instructions(
  122. black_box(SVMStaticMessage::program_instructions_iter(&tx)),
  123. black_box(&feature_set),
  124. )
  125. .is_ok())
  126. })
  127. });
  128. });
  129. }
  130. }
  131. fn bench_process_compute_budget_instructions_mixed(c: &mut Criterion) {
  132. let num_instructions = 355;
  133. for feature_set in [FeatureSet::default(), FeatureSet::all_enabled()] {
  134. c.benchmark_group("bench_process_compute_budget_instructions_mixed")
  135. .throughput(Throughput::Elements(NUM_TRANSACTIONS_PER_ITER as u64))
  136. .bench_function(
  137. format!("{num_instructions} mixed instructions"),
  138. |bencher| {
  139. let payer_keypair = Keypair::new();
  140. let mut ixs: Vec<_> = (0..num_instructions)
  141. .map(|_| {
  142. Instruction::new_with_bincode(
  143. DUMMY_PROGRAM_ID.parse().unwrap(),
  144. &(),
  145. vec![],
  146. )
  147. })
  148. .collect();
  149. ixs.extend(vec![
  150. ComputeBudgetInstruction::request_heap_frame(40 * 1024),
  151. ComputeBudgetInstruction::set_compute_unit_limit(u32::MAX),
  152. ComputeBudgetInstruction::set_compute_unit_price(u64::MAX),
  153. ComputeBudgetInstruction::set_loaded_accounts_data_size_limit(u32::MAX),
  154. transfer(&payer_keypair.pubkey(), &Pubkey::new_unique(), 1),
  155. ]);
  156. let tx = build_sanitized_transaction(&payer_keypair, &ixs);
  157. bencher.iter(|| {
  158. (0..NUM_TRANSACTIONS_PER_ITER).for_each(|_| {
  159. assert!(process_compute_budget_instructions(
  160. black_box(SVMStaticMessage::program_instructions_iter(&tx)),
  161. black_box(&feature_set),
  162. )
  163. .is_ok())
  164. })
  165. });
  166. },
  167. );
  168. }
  169. }
  170. criterion_group!(
  171. benches,
  172. bench_process_compute_budget_instructions_empty,
  173. bench_process_compute_budget_instructions_no_builtins,
  174. bench_process_compute_budget_instructions_compute_budgets,
  175. bench_process_compute_budget_instructions_builtins,
  176. bench_process_compute_budget_instructions_mixed,
  177. );
  178. criterion_main!(benches);