perf: implement SIMD-accelerated event processing and optimize streaming performance

- Add SIMD utilities for fast byte array comparison and discriminator matching
- Optimize event processor with batch processing and memory pool
- Refactor global state management with concurrent data structures
- Remove deprecated batch processing module
- Enhance metrics collection with reduced overhead
- Improve parser efficiency across all protocol implementations
- Add performance benchmarking dependencies (criterion, wide)
- Update documentation and examples for new architecture

Performance improvements:
- SIMD-accelerated byte operations for instruction parsing
- Concurrent HashMap (DashMap) for better multi-threading
- Optimized memory allocation patterns
- Reduced lock contention in event processing pipeline

Breaking changes: Removed batch.rs module, updated parser interfaces
This commit is contained in:
ysq
2025-08-31 22:18:18 +08:00
parent 52a489ae80
commit 74781e5cbe
30 changed files with 1297 additions and 1259 deletions
+4 -10
View File
@@ -2,22 +2,12 @@ pub mod types;
pub mod utils;
pub mod filter;
pub const EMPTY_ID: &str = "";
/// 自动生成UnifiedEvent trait实现的宏
#[macro_export]
macro_rules! impl_unified_event {
// 带有自定义ID表达式的版本
($struct_name:ident, $($field:ident),*) => {
impl $crate::streaming::event_parser::core::traits::UnifiedEvent for $struct_name {
fn id(&self) -> &str {
&self.metadata.id
}
fn clear_id(&mut self) {
self.metadata.id = $crate::streaming::event_parser::common::EMPTY_ID.to_string();
}
fn event_type(&self) -> $crate::streaming::event_parser::common::types::EventType {
self.metadata.event_type.clone()
}
@@ -66,6 +56,10 @@ macro_rules! impl_unified_event {
self.metadata.set_swap_data(swap_data);
}
fn swap_data_is_parsed(&self) -> bool {
self.metadata.swap_data.is_some()
}
fn instruction_outer_index(&self) -> i64 {
self.metadata.instruction_outer_index
}
+21 -25
View File
@@ -2,26 +2,23 @@ use borsh::{BorshDeserialize, BorshSerialize};
use crossbeam_queue::ArrayQueue;
use serde::{Deserialize, Serialize};
use solana_sdk::pubkey::Pubkey;
use solana_transaction_status::{InnerInstruction, UiInstruction};
use std::{
fmt,
hash::{DefaultHasher, Hash, Hasher},
str::FromStr,
sync::Arc,
};
use std::{borrow::Cow, fmt, str::FromStr, sync::Arc};
use crate::{
match_event,
streaming::event_parser::{
protocols::{
bonk::BonkTradeEvent,
pumpfun::PumpFunTradeEvent,
pumpswap::{PumpSwapBuyEvent, PumpSwapSellEvent},
raydium_amm_v4::RaydiumAmmV4SwapEvent,
raydium_clmm::{RaydiumClmmSwapEvent, RaydiumClmmSwapV2Event},
raydium_cpmm::RaydiumCpmmSwapEvent,
streaming::{
common::SimdUtils,
event_parser::{
protocols::{
bonk::BonkTradeEvent,
pumpfun::PumpFunTradeEvent,
pumpswap::{PumpSwapBuyEvent, PumpSwapSellEvent},
raydium_amm_v4::RaydiumAmmV4SwapEvent,
raydium_clmm::{RaydiumClmmSwapEvent, RaydiumClmmSwapV2Event},
raydium_cpmm::RaydiumCpmmSwapEvent,
},
UnifiedEvent,
},
UnifiedEvent,
},
};
@@ -293,8 +290,7 @@ pub struct SwapData {
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, BorshSerialize, BorshDeserialize,
)]
pub struct EventMetadata {
pub id: String,
pub signature: String,
pub signature: Cow<'static, str>,
pub slot: u64,
pub transaction_index: Option<u64>, // 新增:交易在slot中的索引
pub block_time: i64,
@@ -312,8 +308,7 @@ pub struct EventMetadata {
impl EventMetadata {
#[allow(clippy::too_many_arguments)]
pub fn new(
id: String,
signature: String,
signature: Cow<'static, str>,
slot: u64,
block_time: i64,
block_time_ms: i64,
@@ -326,7 +321,6 @@ impl EventMetadata {
transaction_index: Option<u64>,
) -> Self {
Self {
id,
signature,
slot,
block_time,
@@ -343,10 +337,6 @@ impl EventMetadata {
}
}
pub fn set_id(&mut self, id: String) {
self.id = format!("{}-{}-{}", self.signature, self.event_type, id);
}
pub fn set_swap_data(&mut self, swap_data: SwapData) {
self.swap_data = Some(swap_data);
}
@@ -463,6 +453,12 @@ pub fn parse_swap_data_from_next_instructions(
break;
}
let data = &compiled.data;
// 使用 SIMD 验证数据格式
if !SimdUtils::validate_data_format(data, 8) {
continue;
}
let get_pubkey = |i: usize| accounts[compiled.accounts[i] as usize];
let (source, destination, amount) = match data[0] {
12 if compiled.accounts.len() >= 4 => {