diff --git a/Cargo.lock b/Cargo.lock index 89dbb35..982b17f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,7 +104,6 @@ dependencies = [ "anyhow", "aquatic_cli_helpers", "aquatic_http_protocol", - "hashbrown", "mimalloc", "mio", "quickcheck", @@ -112,6 +111,7 @@ dependencies = [ "rand", "rand_distr", "serde", + "slab", ] [[package]] @@ -1680,6 +1680,12 @@ dependencies = [ "termcolor", ] +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + [[package]] name = "smallvec" version = "1.4.0" diff --git a/TODO.md b/TODO.md index 55b3e5b..f7c5d39 100644 --- a/TODO.md +++ b/TODO.md @@ -10,7 +10,6 @@ ## aquatic_http_load_test -* use slab for connections? HashMap not necessary * request sending: too many allocations, likely due to request to byte conversion. optimize! * think about when to open new connections diff --git a/aquatic_http_load_test/Cargo.toml b/aquatic_http_load_test/Cargo.toml index 9fde658..0314652 100644 --- a/aquatic_http_load_test/Cargo.toml +++ b/aquatic_http_load_test/Cargo.toml @@ -12,12 +12,12 @@ name = "aquatic_http_load_test" anyhow = "1" aquatic_cli_helpers = { path = "../aquatic_cli_helpers" } aquatic_http_protocol = { path = "../aquatic_http_protocol" } -hashbrown = { version = "0.7", features = ["serde"] } mimalloc = { version = "0.1", default-features = false } mio = { version = "0.7", features = ["udp", "os-poll", "os-util"] } rand = { version = "0.7", features = ["small_rng"] } rand_distr = "0.2" serde = { version = "1", features = ["derive"] } +slab = "0.4" [dev-dependencies] quickcheck = "0.9" diff --git a/aquatic_http_load_test/src/network.rs b/aquatic_http_load_test/src/network.rs index 1fd1c96..fa918f5 100644 --- a/aquatic_http_load_test/src/network.rs +++ b/aquatic_http_load_test/src/network.rs @@ -2,9 +2,9 @@ use std::sync::atomic::Ordering; use std::time::Duration; use std::io::{Read, Write, ErrorKind}; -use hashbrown::HashMap; use mio::{net::TcpStream, Events, Poll, Interest, Token}; use rand::{rngs::SmallRng, prelude::*}; +use slab::Slab; use crate::common::*; use crate::config::*; @@ -27,6 +27,10 @@ impl Connection { token_counter: &mut usize, ) -> anyhow::Result<()> { let mut stream = TcpStream::connect(config.server_address)?; + + let entry = connections.vacant_entry(); + + *token_counter = entry.key(); poll.registry() .register(&mut stream, Token(*token_counter), Interest::READABLE) @@ -39,9 +43,7 @@ impl Connection { can_send_initial: true, }; - connections.insert(*token_counter, connection); - - *token_counter = token_counter.wrapping_add(1); + entry.insert(connection); Ok(()) } @@ -143,7 +145,10 @@ impl Connection { } -pub type ConnectionMap = HashMap; +pub type ConnectionMap = Slab; + + +const NUM_CONNECTIONS: usize = 128; pub fn run_socket_thread( @@ -153,7 +158,7 @@ pub fn run_socket_thread( ) { let timeout = Duration::from_micros(config.network.poll_timeout_microseconds); - let mut connections: ConnectionMap = HashMap::new(); + let mut connections: ConnectionMap = Slab::with_capacity(NUM_CONNECTIONS); let mut poll = Poll::new().expect("create poll"); let mut events = Events::with_capacity(config.network.poll_event_capacity); let mut rng = SmallRng::from_entropy(); @@ -182,7 +187,7 @@ pub fn run_socket_thread( if event.is_readable(){ let token = event.token(); - if let Some(connection) = connections.get_mut(&token.0){ + if let Some(connection) = connections.get_mut(token.0){ connection.read_response_and_send_request( config, &state, @@ -195,7 +200,7 @@ pub fn run_socket_thread( } if !initial_sent { - for connection in connections.values_mut(){ + for (_, connection) in connections.iter_mut(){ if connection.can_send_initial { connection.send_request(config, &state, &mut rng); @@ -205,7 +210,7 @@ pub fn run_socket_thread( } // Slowly create new connections - if token_counter < 128 && iter_counter % CREATE_CONN_INTERVAL == 0 { + if token_counter < NUM_CONNECTIONS && iter_counter % CREATE_CONN_INTERVAL == 0 { Connection::create_and_register( config, &mut connections,