From c864771bf534e826c024e156cf30272d7c29153f Mon Sep 17 00:00:00 2001 From: Matt Kline Date: Fri, 28 May 2021 20:06:11 -0700 Subject: [PATCH] flt2vhs: Experiment with rustc_hash::FxHasher It claims to be consistently faster than FNV: https://docs.rs/rustc-hash/1.1.0/rustc_hash/struct.FxHasher.html Benchmark it against a larger FLT --- Cargo.lock | 14 +++++++------- flt2vhs/Cargo.toml | 2 +- flt2vhs/src/flt.rs | 20 ++++++++++---------- flt2vhs/src/vhs.rs | 16 ++++++++-------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94e72a3..483b612 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,21 +154,15 @@ name = "flt2vhs" version = "0.8.0" dependencies = [ "anyhow", - "fnv", "humansize", "log", "logsetup", "memmap", "rayon", + "rustc-hash", "structopt", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "heck" version = "0.3.2" @@ -396,6 +390,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "ryu" version = "1.0.5" diff --git a/flt2vhs/Cargo.toml b/flt2vhs/Cargo.toml index b59d649..790c510 100644 --- a/flt2vhs/Cargo.toml +++ b/flt2vhs/Cargo.toml @@ -8,10 +8,10 @@ edition = "2018" [dependencies] anyhow = "1.0" -fnv = "1.0" humansize = "1.0" log = "0.4" logsetup = { path = "../logsetup" } memmap = "0.7" rayon = "1.4" +rustc-hash = "1.1" structopt = "0.3.8" diff --git a/flt2vhs/src/flt.rs b/flt2vhs/src/flt.rs index c7b8368..74b9f7a 100644 --- a/flt2vhs/src/flt.rs +++ b/flt2vhs/src/flt.rs @@ -4,8 +4,8 @@ use std::{io, io::prelude::*, path::Path, time::Instant}; use anyhow::*; -use fnv::{FnvHashMap, FnvHashSet}; use log::*; +use rustc_hash::{FxHashMap, FxHashSet}; use crate::primitives::*; @@ -30,15 +30,15 @@ pub struct Flight { /// Map entity & feature UIDs to callsigns (16 byte blocks for strings) and faction colors. /// /// Use an ordered map to quickly inflate it back to an array on VHS write. - pub callsigns: FnvHashMap, + pub callsigns: FxHashMap, /// A map of unique IDs for entities (all moving objects in game) /// to their position updates and events. - pub entities: FnvHashMap, + pub entities: FxHashMap, /// A map of unique IDs for all features (static objects) /// and their positions. - pub features: FnvHashMap, + pub features: FxHashMap, /// "General" events not associated with any particular entities pub general_events: Vec, @@ -164,10 +164,10 @@ impl Flight { fn merge_entities(self: &mut Flight, next_flight: &Flight, unique_id: &mut i32) { let starting_uid = *unique_id; - let mut used_previous_entities: FnvHashSet = - FnvHashSet::with_capacity_and_hasher(self.entities.len(), Default::default()); - let mut next_to_previous_ids: FnvHashMap = - FnvHashMap::with_capacity_and_hasher(next_flight.entities.len(), Default::default()); + let mut used_previous_entities: FxHashSet = + FxHashSet::with_capacity_and_hasher(self.entities.len(), Default::default()); + let mut next_to_previous_ids: FxHashMap = + FxHashMap::with_capacity_and_hasher(next_flight.entities.len(), Default::default()); for (next_id, next_entity) in &next_flight.entities { let mut closest_entity: Option = None; @@ -280,8 +280,8 @@ impl Flight { fn merge_features(self: &mut Flight, next_flight: &Flight, unique_id: &mut i32) { let starting_uid = *unique_id; - let mut next_to_previous_ids: FnvHashMap = - FnvHashMap::with_capacity_and_hasher(next_flight.features.len(), Default::default()); + let mut next_to_previous_ids: FxHashMap = + FxHashMap::with_capacity_and_hasher(next_flight.features.len(), Default::default()); for (next_id, next_feature) in &next_flight.features { let mut matching_previous = None; diff --git a/flt2vhs/src/vhs.rs b/flt2vhs/src/vhs.rs index dabd484..6cd7ea9 100644 --- a/flt2vhs/src/vhs.rs +++ b/flt2vhs/src/vhs.rs @@ -4,9 +4,9 @@ use std::io; use std::io::prelude::*; use anyhow::*; -use fnv::FnvHashMap; use log::*; use rayon::prelude::*; +use rustc_hash::FxHashMap; use crate::flt::{self, Flight}; use crate::primitives::*; @@ -180,8 +180,8 @@ pub fn write(flight: &Flight, w: W) -> Result { // Some of the feature fields refer to the index of other features. // Let's put those in hash map so we can get constant time lookup. - let mut feature_indexes: FnvHashMap = - FnvHashMap::with_capacity_and_hasher(flight.features.len(), Default::default()); + let mut feature_indexes: FxHashMap = + FxHashMap::with_capacity_and_hasher(flight.features.len(), Default::default()); for (i, id) in mapping.features.iter().map(|m| m.original).enumerate() { feature_indexes.insert(id, i as i32); } @@ -406,7 +406,7 @@ fn write_entities( header: &Header, w: &mut W, ) -> Result { - let mut kind_indexes = FnvHashMap::default(); + let mut kind_indexes = FxHashMap::default(); let mut position_index = 0; let mut event_index = 0; @@ -459,7 +459,7 @@ fn write_entities( fn write_features( flight: &Flight, feature_mapping: &[IdRemap], - feature_indexes: &FnvHashMap, + feature_indexes: &FxHashMap, feature_position_offset: u32, header: &Header, w: &mut W, @@ -503,8 +503,8 @@ fn write_entity_positions( w: &mut CountedWrite, ) -> Result<()> { // Radar targets need to be converted from UIDs to entity indexes. - let mut entity_indexes: FnvHashMap = - FnvHashMap::with_capacity_and_hasher(flight.entities.len(), Default::default()); + let mut entity_indexes: FxHashMap = + FxHashMap::with_capacity_and_hasher(flight.entities.len(), Default::default()); for (i, id) in entity_mapping.iter().map(|m| m.original).enumerate() { entity_indexes.insert(id, i as i32); } @@ -688,7 +688,7 @@ fn write_general_events( fn write_feature_events( flight: &Flight, - feature_indexes: &FnvHashMap, + feature_indexes: &FxHashMap, w: &mut CountedWrite, ) -> Result<()> { for event in &flight.feature_events {