Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add generic heap implementation #4

Closed
wants to merge 11 commits into from
Binary file added .DS_Store
Binary file not shown.
81 changes: 81 additions & 0 deletions benches/bench.rs
Expand Up @@ -12,6 +12,8 @@ mod bench_tests {
use std::collections::BTreeMap;
use std::collections::HashMap;
use test::Bencher;
use sokoban::binary_heap::Heap;
use std::collections::BinaryHeap;

const MAX_SIZE: usize = 20001;
const NUM_BUCKETS: usize = MAX_SIZE >> 2;
Expand Down Expand Up @@ -52,6 +54,17 @@ mod bench_tests {
})
}

#[bench]
fn bench_std_binary_heap_insert_1000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
let mut heap = BinaryHeap::<u128>::default();
b.iter(|| {
for v in 0..1000 {
heap.push(rng.gen::<u128>());
}
})
}

#[bench]
fn bench_sokoban_red_black_tree_insert_1000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
Expand Down Expand Up @@ -100,6 +113,19 @@ mod bench_tests {
})
}

#[bench]
fn bench_sokoban_binary_heap_insert_1000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
let mut sokoban_heap = Heap::<u128, u128, 1001>::default();
let mut slice: Vec<u128> = (0..1000).collect();

b.iter(|| {
for v in 0..1000 {
sokoban_heap._push(rng.gen::<u128>());
}
})
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you paste the benchmark stats?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test bench_tests::bench_sokoban_binary_heap_insert_1000_u128 ... bench: 44,853 ns/iter (+/- 617)
test bench_tests::bench_sokoban_binary_heap_insert_20000_u128 ... bench: 45,293 ns/iter (+/- 1,492)
test bench_tests::bench_sokoban_binary_heap_remove_1000_u128 ... bench: 91,893 ns/iter (+/- 415)

test bench_tests::bench_std_binary_heap_insert_1000_u128 ... bench: 42,571 ns/iter (+/- 1,718)
test bench_tests::bench_std_binary_heap_insert_20000_u128 ... bench: 846,477 ns/iter (+/- 43,306)
test bench_tests::bench_std_binary_heap_remove_1000_u128 ... bench: 70,234 ns/iter (+/- 3,002)

#[bench]
fn bench_sokoban_red_black_tree_insert_1000_u128_stack(b: &mut Bencher) {
let mut rng = rand::thread_rng();
Expand Down Expand Up @@ -166,6 +192,17 @@ mod bench_tests {
})
}

#[bench]
fn bench_std_binary_heap_insert_20000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
let mut heap = BinaryHeap::<u128>::default();
b.iter(|| {
for v in 0..20000 {
heap.push(rng.gen::<u128>());
}
})
}

#[bench]
fn bench_sokoban_red_black_tree_insert_20000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
Expand Down Expand Up @@ -214,6 +251,18 @@ mod bench_tests {
})
}

#[bench]
fn bench_sokoban_binary_heap_insert_20000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
let mut sokoban_heap = Heap::<u128, u128, 1001>::default();

b.iter(|| {
for v in 0..1000 {
sokoban_heap._push(rng.gen::<u128>());
}
})
}

#[bench]
fn bench_std_btree_map_remove_1000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
Expand Down Expand Up @@ -246,6 +295,22 @@ mod bench_tests {
})
}

#[bench]
fn bench_std_binary_heap_remove_1000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
let mut heap = BinaryHeap::<u128>::default();
let mut slice: Vec<u128> = (0..1000).collect();
slice.shuffle(&mut rng);
b.iter(|| {
for v in 0..1000 {
heap.push(rng.gen::<u128>());
}
for k in slice.iter() {
heap.pop();
}
})
}

#[bench]
fn bench_sokoban_red_black_tree_remove_1000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
Expand Down Expand Up @@ -313,4 +378,20 @@ mod bench_tests {
}
})
}

#[bench]
fn bench_sokoban_binary_heap_remove_1000_u128(b: &mut Bencher) {
let mut rng = rand::thread_rng();
let mut sokoban_heap = Heap::<u128, u128, 1001>::default();
let mut slice: Vec<u128> = (0..1000).collect();

b.iter(|| {
for v in 0..1000 {
sokoban_heap._push(rng.gen::<u128>());
}
for k in slice.iter() {
sokoban_heap._pop();
}
})
}
}
23 changes: 15 additions & 8 deletions src/avl_tree.rs
Expand Up @@ -4,7 +4,9 @@ use std::{
ops::{Index, IndexMut},
};

use crate::node_allocator::{FromSlice, NodeAllocator, NodeAllocatorMap, ZeroCopy, SENTINEL, OrderedNodeAllocatorMap};
use crate::node_allocator::{
FromSlice, NodeAllocator, NodeAllocatorMap, OrderedNodeAllocatorMap, ZeroCopy, SENTINEL,
};

// The number of registers (the last register is currently not in use).
const REGISTERS: usize = 4;
Expand Down Expand Up @@ -250,7 +252,7 @@ impl<
};

if reference_node == SENTINEL {
if self.size() >= MAX_SIZE - 1 {
if self.size() >= MAX_SIZE {
return None;
}
reference_node = self.allocator.add_node(new_node);
Expand Down Expand Up @@ -556,7 +558,7 @@ impl<
while self.get_field(node, Field::Left) != SENTINEL {
node = self.get_field(node, Field::Left);
}
return node;
node
}

pub fn find_max_index(&self) -> u32 {
Expand All @@ -567,14 +569,14 @@ impl<
while self.get_field(node, Field::Right) != SENTINEL {
node = self.get_field(node, Field::Right);
}
return node;
node
}

pub fn find_min(&self) -> Option<&V> {
let node = self.find_min_index();
if node == SENTINEL {
None
} else{
} else {
Some(&self.get_node(node).value)
}
}
Expand All @@ -583,7 +585,7 @@ impl<
let node = self.find_max_index();
if node == SENTINEL {
None
} else{
} else {
Some(&self.get_node(node).value)
}
}
Expand Down Expand Up @@ -673,8 +675,13 @@ impl<
self.node = self.tree.get_field(ptr, Field::Right);
// TODO: How does one remove this unsafe?
unsafe {
let node =
(*self.tree.allocator.nodes.as_mut_ptr().add(ptr as usize)).get_value_mut();
let node = (*self
.tree
.allocator
.nodes
.as_mut_ptr()
.add((ptr - 1) as usize))
.get_value_mut();
return Some((&node.key, &mut node.value));
}
}
Expand Down