Skip to content

Commit

Permalink
perf: improve performance of FastVM
Browse files Browse the repository at this point in the history
Use the faster `FxHasher` with `IndexSet`, instead of the default hasher, which is slower.
  • Loading branch information
plusvic committed Sep 3, 2023
1 parent e970c9e commit 75ebc36
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions yara-x/src/re/fast/fastvm.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use indexmap::IndexSet;
use std::hash::BuildHasherDefault;
use std::ops::RangeInclusive;
use std::{cmp, mem};

use itertools::izip;
use memx::memeq;
use rustc_hash::FxHasher;

use crate::re::fast::instr::{Instr, InstrParser};
use crate::re::{Action, CodeLoc, DEFAULT_SCAN_LIMIT};

type IndexSet = indexmap::IndexSet<usize, BuildHasherDefault<FxHasher>>;

/// A faster but less general alternative to [PikeVM].
///
/// `FastVM` is a virtual machine that executes bytecode that evaluates
Expand All @@ -26,15 +29,15 @@ pub(crate) struct FastVM<'r> {
/// far. `IndexSet` is used instead of `HashSet` because insertion order
/// needs to be maintained while iterating the positions and `HashSet`
/// doesn't make any guarantees about iteration order.
positions: IndexSet<usize>,
positions: IndexSet,
}

impl<'r> FastVM<'r> {
/// Creates a new [`FastVM`].
pub fn new(code: &'r [u8]) -> Self {
Self {
code,
positions: IndexSet::new(),
positions: IndexSet::default(),
scan_limit: DEFAULT_SCAN_LIMIT,
}
}
Expand Down Expand Up @@ -73,9 +76,8 @@ impl<'r> FastVM<'r> {
&input[..cmp::min(input.len(), self.scan_limit)]
};

let mut next_positions = IndexSet::new();
let mut next_positions = IndexSet::default();

self.positions.clear();
self.positions.insert(0);

while !self.positions.is_empty() {
Expand All @@ -89,6 +91,7 @@ impl<'r> FastVM<'r> {
for position in &self.positions {
match f(*position) {
Action::Stop => {
self.positions.clear();
return;
}
Action::Continue => {}
Expand Down Expand Up @@ -349,7 +352,7 @@ impl FastVM<'_> {
literal: &[u8],
range: &RangeInclusive<u16>,
position: usize,
next_positions: &mut IndexSet<usize>,
next_positions: &mut IndexSet,
) {
let jmp_min = *range.start() as usize;
let jmp_max = cmp::min(input.len(), *range.end() as usize + 1);
Expand All @@ -374,7 +377,7 @@ impl FastVM<'_> {
literal: &[u8],
range: &RangeInclusive<u16>,
position: usize,
next_positions: &mut IndexSet<usize>,
next_positions: &mut IndexSet,
) {
let jmp_range = input.len().saturating_sub(*range.end() as usize + 1)
..input.len().saturating_sub(*range.start() as usize);
Expand Down

0 comments on commit 75ebc36

Please sign in to comment.