Skip to content

Commit

Permalink
Merge pull request #6 from raunakab/benches
Browse files Browse the repository at this point in the history
Benches
  • Loading branch information
Raunak Bhagat authored May 31, 2024
2 parents edd3247 + 77ce8b6 commit a4f9df3
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 17 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Provides constant access to a node given its id.
Especially useful for UI DOMs.

## Implementation

`quicktree` uses a map-based implementation of a tree.
Rather than the "naive" implementation of a tree in which each node contains a vector of child nodes, we instead store nodes in a map, indexable by an id.
Each node then stores the *ids* of its children, rather than a pointer to its children directly.
Expand All @@ -22,7 +23,25 @@ The latter instead offers constant time access to a node given its unique id.

This will be especially appealing for applications such as UI DOMs.

## Usage

#### Cargo
Add the following to your `Cargo.toml`:

```toml
[dependencies.quicktree]
git = "https://github.com/raunakab/quicktree.git"
```

#### Buck2
Steve Klabnik has an amazing series of posts on how to [include third-party dependencies](https://steveklabnik.com/writing/using-cratesio-with-buck) (vendored or non-vendored) in your `buck2` project.
This crate does *not* contain any build scripts, so you should be off and running quickly.

#### Other
You will need search up your specific build tool's docs in order to get up and running with `quicktree` in your project.

## Example

```rust
use quicktree::Tree;

Expand All @@ -46,5 +65,22 @@ assert_eq!(*tree.get(child_2_id).unwrap().value, "there!");
assert_eq!(tree.get(child_3_id), None);
```

## Performance

Based off of some limited benches (on my desktop PC), the following metrics are being observed:

| Test | Average Time \[microseconds\] |
|---|---|
| Inserting 1000 children | 24.172 |
| Inserting 1000 children and then removing the root | 24.724 |

Please note that these results are hardware specific, and *should not be used for comparisons against other implementations*!
You can run these results yourself by cloning the repository and running:

```sh
cargo bench
```

## License

Licensed under the [MIT License](./LICENSE-MIT).
21 changes: 4 additions & 17 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use quicktree::Tree;
mod insertion;
mod removal;

fn insert((): ()) {
let mut tree = Tree::<usize>::default();
let root_id = tree.insert_root(black_box(0));
(0..1000).into_iter().for_each(|value| {
let _ = tree.insert(black_box(root_id), black_box(value)).unwrap();
});
}
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn insert_and_remove_root((): ()) {
let mut tree = Tree::<usize>::default();
let root_id = tree.insert_root(black_box(0));
(0..1000).into_iter().for_each(|value| {
let _ = tree.insert(black_box(root_id), black_box(value)).unwrap();
});
let _ = tree.remove(black_box(root_id)).unwrap();
}
use crate::{insertion::insert, removal::insert_and_remove_root};

fn run_benches(c: &mut Criterion) {
c.bench_function("Insert 1000 children", |b| {
Expand Down
11 changes: 11 additions & 0 deletions benches/insertion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use criterion::black_box;
use quicktree::Tree;

pub fn insert((): ()) {
let mut tree = Tree::<usize>::default();
let root_id = tree.insert_root(black_box(0));
(0..1000).into_iter().for_each(|value| {
let _ = tree.insert(black_box(root_id), black_box(value)).unwrap();
});
assert_eq!(tree.size(), 1001);
}
12 changes: 12 additions & 0 deletions benches/removal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use criterion::black_box;
use quicktree::Tree;

pub fn insert_and_remove_root((): ()) {
let mut tree = Tree::<usize>::default();
let root_id = tree.insert_root(black_box(0));
(0..1000).into_iter().for_each(|value| {
let _ = tree.insert(black_box(root_id), black_box(value)).unwrap();
});
let _ = tree.remove(black_box(root_id)).unwrap();
assert!(tree.is_empty());
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ impl<V> Tree<V> {

// gets/sets:

pub fn size(&self) -> usize {
self.nodes.len()
}

pub fn get_root_id(&self) -> Option<Id> {
self.root_id
}
Expand Down

0 comments on commit a4f9df3

Please sign in to comment.