diff --git a/Cargo.toml b/Cargo.toml index 785f036a..fa416777 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ dmsort = {version = "1.0.0", optional = true} toml-dep = { version = "0.5.8", package="toml", optional = true } [features] -default = ["cellularnoise", "dmi", "file", "git", "http", "json", "log", "noise", "sql", "toml", "url"] +default = ["cellularnoise", "dmi", "file", "git", "http", "json", "log", "noise", "sql", "time", "toml", "url"] # default features cellularnoise = ["rand"] @@ -56,6 +56,7 @@ http = ["reqwest", "serde", "serde_json", "once_cell", "jobs"] json = ["serde", "serde_json"] log = ["chrono"] sql = ["mysql", "serde", "serde_json", "once_cell", "dashmap", "jobs"] +time = [] toml = ["serde", "serde_json", "toml-dep"] url = ["url-dep", "percent-encoding"] diff --git a/README.md b/README.md index ede6685f..a997702a 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ The default features are: * sql: Asynchronous MySQL/MariaDB client library. * noise: 2d Perlin noise. * toml: TOML parser. +* time: High-accuracy time measuring. Additional features are: * hash: Faster replacement for `md5`, support for SHA-1, SHA-256, and SHA-512. Requires OpenSSL on Linux. diff --git a/dmsrc/time.dm b/dmsrc/time.dm new file mode 100644 index 00000000..56e1b0c7 --- /dev/null +++ b/dmsrc/time.dm @@ -0,0 +1,3 @@ +#define rustg_time_microseconds(id) text2num(call(RUST_G, "time_microseconds")(id)) +#define rustg_time_milliseconds(id) text2num(call(RUST_G, "time_milliseconds")(id)) +#define rustg_time_reset(id) call(RUST_G, "time_reset")(id) diff --git a/src/lib.rs b/src/lib.rs index f875f457..33ca3dc0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,8 @@ pub mod log; pub mod noise_gen; #[cfg(feature = "sql")] pub mod sql; +#[cfg(feature = "time")] +pub mod time; #[cfg(feature = "toml")] pub mod toml; #[cfg(feature = "unzip")] diff --git a/src/time.rs b/src/time.rs new file mode 100644 index 00000000..9a9960af --- /dev/null +++ b/src/time.rs @@ -0,0 +1,38 @@ +use std::{ + cell::RefCell, + collections::hash_map::{Entry, HashMap}, + time::Instant, +}; + +thread_local!( static INSTANTS: RefCell> = RefCell::new(HashMap::new()) ); + +byond_fn! { time_microseconds(instant_id) { + INSTANTS.with(|instants| { + let mut map = instants.borrow_mut(); + let instant = match map.entry(instant_id.into()) { + Entry::Occupied(elem) => elem.into_mut(), + Entry::Vacant(elem) => elem.insert(Instant::now()), + }; + Some(instant.elapsed().as_micros().to_string()) + }) +} } + +byond_fn! { time_milliseconds(instant_id) { + INSTANTS.with(|instants| { + let mut map = instants.borrow_mut(); + let instant = match map.entry(instant_id.into()) { + Entry::Occupied(elem) => elem.into_mut(), + Entry::Vacant(elem) => elem.insert(Instant::now()), + }; + Some(instant.elapsed().as_millis().to_string()) + }) +} } + +byond_fn! { time_reset(instant_id) { + INSTANTS.with(|instants| { + let mut map = instants.borrow_mut(); + map.insert(instant_id.into(), Instant::now()); + Some("") + }) +} } +