Skip to content

Commit

Permalink
Implement a KPatternStack to reduce allocations during IDFS.
Browse files Browse the repository at this point in the history
Performance impact is small but seems to be roughly a 3% for 3x3x3:

    git checkout [this commit]
    cargo build
    cp ./target/release/twsearch /tmp/twsearch-with-stack

    git checkout 1ec95de
    cargo build
    cp ./target/release/twsearch /tmp/twsearch-without-stack

    hyperfine \
      '/tmp/twsearch-with-stack    search --generator-moves F,R,D,B,L --scramble-alg U "samples/json/3x3x3/3x3x3-Reid.def.json"' \
      '/tmp/twsearch-without-stack search --generator-moves F,R,D,B,L --scramble-alg U "samples/json/3x3x3/3x3x3-Reid.def.json"'
  • Loading branch information
lgarron committed Oct 9, 2024
1 parent 1ec95de commit b5af560
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
19 changes: 14 additions & 5 deletions src/rs/_internal/search/idf_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use crate::_internal::{
SearchGenerators, SearchLogger, CANONICAL_FSM_START_STATE,
};

use super::KPatternStack;

const MAX_SUPPORTED_SEARCH_DEPTH: usize = 500; // TODO: increase

#[allow(clippy::enum_variant_names)]
Expand Down Expand Up @@ -220,6 +222,7 @@ impl IDFSearch {

let search_pattern = search_pattern.clone();

let mut kpattern_stack = KPatternStack::new(search_pattern);
for remaining_depth in individual_search_data
.individual_search_options
.get_min_depth()
Expand All @@ -239,7 +242,7 @@ impl IDFSearch {
.start_depth(remaining_depth, Some("Starting search…"));
let recursion_result = self.recurse(
&mut individual_search_data,
&search_pattern,
&mut kpattern_stack,
CANONICAL_FSM_START_STATE,
remaining_depth,
SolutionMoves(None),
Expand All @@ -257,14 +260,15 @@ impl IDFSearch {
fn recurse(
&self,
individual_search_data: &mut IndividualSearchData,
current_pattern: &KPattern,
kpattern_stack: &mut KPatternStack,
current_state: CanonicalFSMState,
remaining_depth: usize,
solution_moves: SolutionMoves,
) -> SearchRecursionResult {
individual_search_data
.recursive_work_tracker
.record_recursive_call();
let current_pattern = kpattern_stack.current_pattern();
if remaining_depth == 0 {
if let Some(previous_moves) = solution_moves.0 {
if is_move_disallowed(
Expand Down Expand Up @@ -333,16 +337,21 @@ impl IDFSearch {
// TODO: is it always safe to `break` here?
continue;
}
match self.recurse(

kpattern_stack.push(&move_transformation_info.transformation);
let recursive_result = self.recurse(
individual_search_data,
&current_pattern.apply_transformation(&move_transformation_info.transformation),
kpattern_stack,
next_state,
remaining_depth - 1,
SolutionMoves(Some(&SolutionPreviousMoves {
latest_move: &move_transformation_info.r#move,
previous_moves: &solution_moves,
})),
) {
);
kpattern_stack.pop();

match recursive_result {
SearchRecursionResult::DoneSearching() => {
return SearchRecursionResult::DoneSearching();
}
Expand Down
38 changes: 38 additions & 0 deletions src/rs/_internal/search/kpattern_stack.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use cubing::kpuzzle::{KPattern, KTransformation};

pub(crate) struct KPatternStack {
stack: Vec<KPattern>,
current_idx: usize,
}

impl KPatternStack {
pub fn new(root_kpattern: KPattern) -> Self {
Self {
stack: vec![root_kpattern],
current_idx: 0,
}
}

pub fn push(&mut self, transformation: &KTransformation) {
self.current_idx += 1;
if self.current_idx >= self.stack.len() {
self.stack
.push(self.stack[self.current_idx - 1].apply_transformation(transformation))
} else {
// We have to use `split_at_mut` so that we can borrow both the read and write entries at the same time: https://doc.rust-lang.org/nomicon/borrow-splitting.html
let (left, right) = self.stack.split_at_mut(self.current_idx);

left.last()
.unwrap()
.apply_transformation_into(transformation, right.first_mut().unwrap());
}
}

pub fn current_pattern(&self) -> &KPattern {
&self.stack[self.current_idx]
}

pub fn pop(&mut self) {
self.current_idx -= 1;
}
}
3 changes: 3 additions & 0 deletions src/rs/_internal/search/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ pub(crate) use recursive_work_tracker::*;

mod search_logger;
pub use search_logger::*;

mod kpattern_stack;
pub(crate) use kpattern_stack::*;

0 comments on commit b5af560

Please sign in to comment.