Skip to content

Commit 5cd2b5b

Browse files
committed
experiment hashmap for temp lookup
1 parent 34f6827 commit 5cd2b5b

File tree

4 files changed

+43
-13
lines changed

4 files changed

+43
-13
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
measurement_data*.txt
22
benchmark*.json
33
target/
4-
Cargo.lock
4+
Cargo.lock
5+
perf.data*

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ fixed = "1.24.0"
1212
memmap2 = "0.9.3"
1313
mimalloc = "0.1.39"
1414
rayon = "1.8.0"
15+
lazy_static = "1.4"
16+
num_cpus = "1.16.0"
1517

1618
[[bin]]
1719
name = "1brc"
@@ -28,4 +30,4 @@ panic = "abort"
2830
debug-assertions = false
2931
overflow-checks = false
3032
lto = true
31-
incremental = false
33+
incremental = false

src/Lucretiel.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,4 @@ fn main() {
173173

174174
// No reason to waste time freeing memory and closing files and stuff
175175
std::process::exit(0);
176-
}
176+
}

src/main.rs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,21 @@ use std::{
66
env::args_os,
77
fs::File,
88
io::{stdout, Write as _},
9-
path::Path, sync::{Arc, Mutex},
9+
path::Path,
10+
sync::{Arc, Mutex},
1011
};
1112

1213
use fixed::types::I48F16;
1314
use fxhash::FxHashMap;
1415
use memmap2::Mmap;
1516
use mimalloc::MiMalloc;
1617
use rayon::{
17-
iter::{ParallelIterator, IntoParallelRefIterator},
18+
iter::{IntoParallelRefIterator, ParallelIterator, FromParallelIterator},
1819
slice::{ParallelSlice, ParallelSliceMut},
1920
};
2021

21-
use std::hash::{Hash, Hasher};
22+
use lazy_static::lazy_static;
23+
use std::borrow::Cow;
2224

2325
type Value = I48F16;
2426

@@ -89,12 +91,38 @@ fn fast_parse(input: &[u8]) -> Value {
8991
Value::from_num(int) / Value::from_num(10)
9092
}
9193

94+
#[inline(always)]
95+
/// experimental and cost more than fast_parse (hashing+lookup cost > than trick above)
96+
fn lookup_temp(input: &[u8]) -> Value {
97+
//get values from hashmap instead of parsing them.
98+
//println!("getting value {:?}", std::str::from_utf8(input));
99+
let key = Cow::Borrowed(input);
100+
*TEMPURATURE_HASHMAP.get(&key).unwrap()
101+
}
102+
92103
fn write_pair(city: &[u8], record: &Record, out: &mut Vec<u8>) {
93104
out.extend_from_slice(city);
94105
out.push(b'=');
95106
record.write(out);
96107
}
97108

109+
//store possible temp values -100.9 => 100.9
110+
lazy_static! {
111+
static ref TEMPURATURE_HASHMAP: FxHashMap<Cow<'static, [u8]>, Value> = {
112+
let mut hashmap = FxHashMap::with_capacity_and_hasher(100*10*2+10,Default::default());
113+
114+
// Populate the hashmap with keys and values
115+
for i in (-1009..=1009).step_by(1) {
116+
let value = i as f64 / 10.0;
117+
let key_str = format!("{:.1}", value);
118+
let key_bytes = key_str.as_bytes().to_vec(); // Convert to owned Vec<u8>
119+
let key_cow: Cow<'static, [u8]> = Cow::Owned(key_bytes);
120+
hashmap.insert(key_cow, Value::from_num(value));
121+
}
122+
hashmap
123+
};
124+
}
125+
98126
fn main() {
99127
// Simple mega parallel rayon solution
100128
let path = args_os()
@@ -140,13 +168,12 @@ fn main() {
140168
map1
141169
});
142170

143-
let mut sorted_data: Vec<(&[u8], &Record)> =
144-
data.par_iter().map(|(&city, record)| (city, record)).collect();
171+
let mut sorted_data: Vec<(&&[u8], &Record)> = Vec::from_par_iter(data.par_iter());
145172

146173
// Use Rayon to parallelize the sorting in chunks.
147174
// TODO : adjust the Chunk size depending on the target.
148-
const CHUNK_SIZE: usize = 1000000;
149-
sorted_data.par_chunks_mut(CHUNK_SIZE).for_each(|chunk| {
175+
let chunk_size: usize = 1_000_000_000/ num_cpus::get() ;
176+
sorted_data.par_chunks_mut(chunk_size).for_each(|chunk| {
150177
chunk.par_sort_unstable_by_key(|&(city, _)| city);
151178
});
152179

@@ -165,10 +192,10 @@ fn main() {
165192

166193
out.push(b'{');
167194

168-
let out = Arc::new(Mutex::new(out));
195+
let out = Arc::new(Mutex::new(out));
169196

170197
// Parallelize writing to output
171-
sorted_data.par_chunks(CHUNK_SIZE).for_each(|chunk| {
198+
sorted_data.par_chunks(chunk_size).for_each(|chunk| {
172199
let mut local_out = Vec::with_capacity(chunk.len() * est_record_size);
173200

174201
if let Some(&(city, record)) = chunk.first() {
@@ -195,4 +222,4 @@ fn main() {
195222

196223
// No reason to waste time freeing memory and closing files and stuff
197224
std::process::exit(0);
198-
}
225+
}

0 commit comments

Comments
 (0)