From 979a64e72c52c1f87192ae80e86dd70066161ff2 Mon Sep 17 00:00:00 2001 From: WSRer <1749094641@qq.com> Date: Thu, 21 Nov 2024 09:34:16 +0800 Subject: [PATCH 1/5] simd-json --- Cargo.lock | 268 ++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 4 +- src/app.rs | 14 ++- src/bytecode.rs | 28 ++--- src/lsp_message.rs | 22 ++-- src/main.rs | 4 + tests/bytecode_test.rs | 36 +++--- 7 files changed, 329 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bea9f14..246d363 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,18 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] [[package]] name = "aho-corasick" @@ -11,6 +23,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" + [[package]] name = "anstream" version = "0.6.5" @@ -65,6 +83,12 @@ version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca87830a3e3fb156dc96cfbd31cb620265dd053be734723f22b760d6cc3c3051" +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + [[package]] name = "bitflags" version = "1.3.2" @@ -77,6 +101,21 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -216,8 +255,10 @@ dependencies = [ "env_logger", "lazy_static", "log", + "mimalloc", "serde", "serde_json", + "simd-json", "smallvec", "tempfile", "which", @@ -270,12 +311,54 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "float-cmp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" +dependencies = [ + "num-traits", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "halfbrown" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8588661a8607108a5ca69cab034063441a0413a0b041c13618a7dd348021ef6f" +dependencies = [ + "hashbrown", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + [[package]] name = "heck" version = "0.4.1" @@ -326,6 +409,15 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -338,6 +430,16 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libmimalloc-sys" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -356,6 +458,24 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "mimalloc" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" +dependencies = [ + "libmimalloc-sys", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -389,6 +509,26 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "ref-cast" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53313ec9f12686aeeffb43462c3ac77aa25f590a5f630eb2cde0de59417b29c7" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2566c4bf6845f2c2e83b27043c3f5dfcd5ba8f2937d6c00dc009bfb51a079dc4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.43", +] + [[package]] name = "regex" version = "1.10.2" @@ -492,6 +632,33 @@ dependencies = [ "serde", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-json" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2bcf6c6e164e81bc7a5d49fc6988b3d515d9e8c07457d7b74ffb9324b9cd40" +dependencies = [ + "getrandom", + "halfbrown", + "ref-cast", + "serde", + "serde_json", + "simdutf8", + "value-trait", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "smallvec" version = "1.11.2" @@ -586,6 +753,85 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "value-trait" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9170e001f458781e92711d2ad666110f153e4e50bfd5cbd02db6547625714187" +dependencies = [ + "float-cmp", + "halfbrown", + "itoa", + "ryu", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.43", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.43", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + [[package]] name = "which" version = "6.0.1" @@ -700,3 +946,23 @@ name = "winsafe" version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.43", +] diff --git a/Cargo.toml b/Cargo.toml index d73d3b1..0ae3bef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,8 @@ edition = "2021" [dependencies] serde = { version = "1.0", features = ["derive"]} -serde_json = "1.0" anyhow = "1.0" +serde_json = "1.0" lazy_static = "1.4" smallvec = "1.11" env_logger = "0.10" @@ -16,6 +16,8 @@ log = "0.4.20" clap = { version = "4.4", features = ["derive", "cargo"] } clap-verbosity-flag = "2.1.1" which = "6.0.1" +simd-json = "0.14.3" +mimalloc = "0.1.43" [[example]] name = "native-json-parser" diff --git a/src/app.rs b/src/app.rs index f140898..cfeb7ab 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2,7 +2,7 @@ use std::sync::{mpsc, Arc, atomic::{AtomicI32, self}}; use log::{warn, info, debug}; use anyhow::{Result, Context}; -use serde_json as json; +use simd_json as json; use crate::{rpcio, bytecode::{self, BytecodeOptions}}; use crate::lsp_message::{LspRequest, LspResponse, LspResponseError}; @@ -30,13 +30,15 @@ fn process_client_reader(reader: impl std::io::Read, client_channel_pub: mpsc::Sender) -> Result<()> { let mut bufreader = std::io::BufReader::new(reader); loop { - let msg = rpcio::rpc_read(&mut bufreader)?; + let mut msg = rpcio::rpc_read(&mut bufreader)?; if msg.is_empty() { break } if server_channel_counter.load(atomic::Ordering::Acquire) >= MAX_PENDING_MSG_COUNT { - let lsp_request: LspRequest = json::from_str(&msg)?; + let lsp_request: LspRequest = unsafe { + json::from_str(&mut msg)? + }; // only cancel when it's not notification if !lsp_request.is_notification() { warn!("Buffer full, rejecting request: {} (id={:?})", @@ -44,7 +46,7 @@ fn process_client_reader(reader: impl std::io::Read, let resp = LspResponse { jsonrpc: lsp_request.jsonrpc, id: lsp_request.id.unwrap(), - result: json::Value::Null, + result: serde_json::Value::Null, error: Some(LspResponseError { code: -32803, message: "[emacs-lsp-booster] Server is busy".to_string(), @@ -67,12 +69,12 @@ fn process_server_reader(reader: impl std::io::Read, bytecode_options: Option) -> Result<()> { let mut bufreader = std::io::BufReader::new(reader); loop { - let msg = rpcio::rpc_read(&mut bufreader)?; + let mut msg = rpcio::rpc_read(&mut bufreader)?; if msg.is_empty() { break } if let Some(ref bytecode_options) = bytecode_options { - let json_val = json::from_str(&msg)?; + let json_val = unsafe {json::from_str(&mut msg)?}; match bytecode::generate_bytecode_repl(&json_val, bytecode_options.clone()) { Ok(bytecode_str) => { debug!("server->client: json {} bytes; converted to bytecode, {} bytes", diff --git a/src/bytecode.rs b/src/bytecode.rs index 796a88e..f62da3e 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use std::str::FromStr; use anyhow::{Result, bail}; -use serde_json as json; +use simd_json as json; use smallvec::smallvec; @@ -242,7 +242,7 @@ impl BytecodeCompiler { self.ops.push(Op::PushConstant(idx)) } - fn compile_value_array(&mut self, arr: &[json::Value]) { + fn compile_value_array(&mut self, arr: &[serde_json::Value]) { if arr.is_empty() { self.compile_constant_op(LispObject::Symbol("vector".into())); self.ops.push(Op::Call(0)); @@ -272,7 +272,7 @@ impl BytecodeCompiler { } } - fn compile_value_map_plist_or_alist(&mut self, map: &json::Map, alist: bool) { + fn compile_value_map_plist_or_alist(&mut self, map: &serde_json::Map, alist: bool) { let list_len = if alist { map.len() } else { map.len() * 2 }; // see below if list_len < (1 << 16) && list_len >= (1 << 8) { @@ -305,7 +305,7 @@ impl BytecodeCompiler { } } - fn compile_value_map_hashtable(&mut self, map: &json::Map) { + fn compile_value_map_hashtable(&mut self, map: &serde_json::Map) { self.compile_constant_op(LispObject::Symbol("make-hash-table".into())); self.compile_constant_op(LispObject::Keyword("test".into())); self.compile_constant_op(LispObject::Symbol("equal".into())); @@ -323,31 +323,31 @@ impl BytecodeCompiler { } } - fn compile_value(&mut self, value: &json::Value) { + fn compile_value(&mut self, value: &serde_json::Value) { match value { - &json::Value::Null => { + &serde_json::Value::Null => { self.compile_constant_op(self.options.null_value.clone()); }, - &json::Value::Bool(false) => { + &serde_json::Value::Bool(false) => { self.compile_constant_op(self.options.false_value.clone()); }, - &json::Value::Bool(true) => { + &serde_json::Value::Bool(true) => { self.compile_constant_op(LispObject::T); }, - &json::Value::Number(ref num) => { + &serde_json::Value::Number(ref num) => { if num.is_f64() { self.compile_constant_op(LispObject::Float(num.to_string())); } else { self.compile_constant_op(LispObject::Int(num.as_i64().unwrap())); } }, - &json::Value::String(ref s) => { + &serde_json::Value::String(ref s) => { self.compile_constant_op(LispObject::Str(s.clone())); }, - &json::Value::Array(ref arr) => { + &serde_json::Value::Array(ref arr) => { self.compile_value_array(&arr); }, - &json::Value::Object(ref map) => { + &serde_json::Value::Object(ref map) => { match self.options.object_type { ObjectType::Plist => self.compile_value_map_plist_or_alist(&map, false), ObjectType::Alist => self.compile_value_map_plist_or_alist(&map, true), @@ -357,7 +357,7 @@ impl BytecodeCompiler { } } - fn compile(&mut self, value: &json::Value) { + fn compile(&mut self, value: &serde_json::Value) { self.compile_value(value); self.ops.push(Op::Return); } @@ -429,7 +429,7 @@ impl BytecodeCompiler { } } -pub fn generate_bytecode_repl(value: &json::Value, options: BytecodeOptions) -> Result { +pub fn generate_bytecode_repl(value: &serde_json::Value, options: BytecodeOptions) -> Result { let mut compiler = BytecodeCompiler { options, ops: Vec::new(), diff --git a/src/lsp_message.rs b/src/lsp_message.rs index d14d7a5..62c9d37 100644 --- a/src/lsp_message.rs +++ b/src/lsp_message.rs @@ -1,4 +1,3 @@ -use serde_json as json; use serde::{ Deserialize, Serialize }; // or notification @@ -7,7 +6,7 @@ pub struct LspRequest { pub jsonrpc: String, pub id: Option, pub method: String, - pub params: json::Value, + pub params: serde_json::Value, } impl LspRequest { @@ -26,25 +25,26 @@ pub struct LspResponseError { pub struct LspResponse { pub jsonrpc: String, pub id: i32, - pub result: json::Value, + pub result: serde_json::Value, pub error: Option, } #[cfg(test)] mod test { use super::*; + use simd_json as json; #[test] fn test_lsp_request() { - let json_str = r#"{ + let mut json_str = r#"{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "xxx": 123 } - }"#; - let req: LspRequest = json::from_str(json_str).unwrap(); + }"#.to_string(); + let req: LspRequest = unsafe {json::from_str(&mut json_str).unwrap()}; assert_eq!(req.jsonrpc, "2.0"); assert_eq!(req.id, Some(1)); assert_eq!(req.method, "initialize"); @@ -53,12 +53,14 @@ mod test { #[test] fn test_lsp_request_notification() { - let json_str = r#"{ + let mut json_str = r#"{ "jsonrpc": "2.0", "method": "initialized", "params": {} - }"#; - let req: LspRequest = json::from_str(json_str).unwrap(); + }"#.to_string(); + let req: LspRequest = unsafe { + json::from_str(&mut json_str).unwrap() + }; assert_eq!(req.id, None); assert_eq!(req.method, "initialized"); assert_eq!(req.is_notification(), true); @@ -69,7 +71,7 @@ mod test { let resp = LspResponse { jsonrpc: "2.0".to_string(), id: 1, - result: json::Value::Null, + result: serde_json::Value::Null, error: Some(LspResponseError { code: 123, message: "asdf".to_string(), diff --git a/src/main.rs b/src/main.rs index 19d3b0a..a67a8bd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,10 @@ use clap::Parser; use emacs_lsp_booster::app; use emacs_lsp_booster::bytecode; +use mimalloc::MiMalloc; + +#[global_allocator] +static GLOBAL: MiMalloc = MiMalloc; #[derive(Parser)] diff --git a/tests/bytecode_test.rs b/tests/bytecode_test.rs index dad11ac..4e7cc3a 100644 --- a/tests/bytecode_test.rs +++ b/tests/bytecode_test.rs @@ -1,12 +1,12 @@ -use serde_json as json; +use simd_json as json; use anyhow::Result; use tempfile; use emacs_lsp_booster::bytecode; -fn run_one_test(json_str: &str, object_type: bytecode::ObjectType) -> Result<()> { - let json_value: json::Value = json::from_str(json_str)?; +fn run_one_test(json_str: &mut str, object_type: bytecode::ObjectType) -> Result<()> { + let json_value: serde_json::Value = unsafe{json::from_str(json_str)?}; let json_str_nowhitespaces = json_value.to_string(); let bytecode = bytecode::generate_bytecode_repl(&json_value, bytecode::BytecodeOptions { object_type: object_type.clone(), @@ -50,43 +50,49 @@ fn run_one_test(json_str: &str, object_type: bytecode::ObjectType) -> Result<()> #[test] fn test_bytecode() { // unicode test - run_one_test(r#"{"a":"ÀÁÂÃÄÅÆÇÈÉÊËÌ abcd \n 你好世界"}"#, bytecode::ObjectType::Plist).unwrap(); + let mut s = String::from(r#"{"a":"ÀÁÂÃÄÅÆÇÈÉÊËÌ abcd \n 你好世界"}"#); + run_one_test(&mut s, bytecode::ObjectType::Plist).unwrap(); for object_type in vec![bytecode::ObjectType::Plist, bytecode::ObjectType::Alist, bytecode::ObjectType::Hashtable] { eprintln!("Testing completion.json (~100KB), object type = {:?}", object_type); - run_one_test(include_str!("./data/completion.json"), object_type).unwrap(); + let mut s = String::from(include_str!("./data/completion.json")); + run_one_test(&mut s, object_type).unwrap(); eprintln!("Testing completion2.json (~100KB), object type = {:?}", object_type); - run_one_test(include_str!("./data/completion2.json"), object_type).unwrap(); + let mut s = String::from(include_str!("./data/completion2.json")); + run_one_test(&mut s, object_type).unwrap(); eprintln!("Testing completion3.json (~4KB), object type = {:?}", object_type); - run_one_test(include_str!("./data/completion3.json"), object_type).unwrap(); + let mut s = String::from(include_str!("./data/completion3.json")); + run_one_test(&mut s, object_type).unwrap(); eprintln!("Testing publishDiagnostics.json (~12KB), object type = {:?}", object_type); - run_one_test(include_str!("./data/publishDiagnostics.json"), object_type).unwrap(); + let mut s = String::from(include_str!("./data/publishDiagnostics.json")); + run_one_test(&mut s, object_type).unwrap(); eprintln!("Testing publishDiagnostics2.json (~12KB), object type = {:?}", object_type); - run_one_test(include_str!("./data/publishDiagnostics2.json"), object_type).unwrap(); + let mut s = String::from(include_str!("./data/publishDiagnostics2.json")); + run_one_test(&mut s, object_type).unwrap(); } { eprintln!("Testing huge array (100000 elements)"); - let value = json::Value::Array( - (0..100000).map(|x| json::Value::String(format!("{}", x))) + let value = serde_json::Value::Array( + (0..100000).map(|x| serde_json::Value::String(format!("{}", x))) .collect() ); - run_one_test(&value.to_string(), bytecode::ObjectType::Plist).unwrap(); + run_one_test(&mut value.to_string(), bytecode::ObjectType::Plist).unwrap(); } { eprintln!("Testing huge map (100000 elements)"); - let value = json::Value::Object( + let value = serde_json::Value::Object( (0..100000).map(|x| (format!("x{}", x), - json::Value::Number(x.into()))) + serde_json::Value::Number(x.into()))) .collect() ); - run_one_test(&value.to_string(), bytecode::ObjectType::Plist).unwrap(); + run_one_test(&mut value.to_string(), bytecode::ObjectType::Plist).unwrap(); } } From 9e9d477e19315268092c84a5f1208e99a721841c Mon Sep 17 00:00:00 2001 From: WSRer <1749094641@qq.com> Date: Tue, 14 Jan 2025 15:37:52 +0800 Subject: [PATCH 2/5] update git actions --- .github/workflows/release.yml | 1 + README.md | 2 +- src/bytecode.rs | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 42ba152..9aa2cd4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,5 +18,6 @@ jobs: uses: rust-build/rust-build.action@v1.4.4 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RUSTFLAGS: '-C target-cpu=native' with: RUSTTARGET: ${{ matrix.target }} diff --git a/README.md b/README.md index b195016..bab9a62 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ A flake for nix users is available [here](https://github.com/slotThe/emacs-lsp-b Alternatively, you may build the target locally: 1. Setup [Rust toolchain](https://www.rust-lang.org/tools/install) -2. Run `cargo build --release` +2. Run `RUSTFLAGS='-C target-cpu=native' cargo build --release` 3. Find the built binary in `target/release/emacs-lsp-booster` Then, put the `emacs-lsp-booster` binary in your $PATH (e.g. `~/.local/bin`). diff --git a/src/bytecode.rs b/src/bytecode.rs index f62da3e..9b85584 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -2,7 +2,6 @@ use std::collections::BTreeMap; use std::str::FromStr; use anyhow::{Result, bail}; -use simd_json as json; use smallvec::smallvec; From 206d0a0bde68c2c683466b339280ba9c349876cf Mon Sep 17 00:00:00 2001 From: WSRer <1749094641@qq.com> Date: Thu, 16 Jan 2025 19:15:08 +0800 Subject: [PATCH 3/5] use snmalloc --- Cargo.lock | 48 ++++++++++++++++++++++++++++-------------------- Cargo.toml | 2 +- src/main.rs | 3 +-- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 246d363..7310917 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,6 +172,15 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +[[package]] +name = "cmake" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.0" @@ -255,11 +264,11 @@ dependencies = [ "env_logger", "lazy_static", "log", - "mimalloc", "serde", "serde_json", "simd-json", "smallvec", + "snmalloc-rs", "tempfile", "which", ] @@ -430,16 +439,6 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" -[[package]] -name = "libmimalloc-sys" -version = "0.1.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -458,15 +457,6 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" -[[package]] -name = "mimalloc" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" -dependencies = [ - "libmimalloc-sys", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -665,6 +655,24 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "snmalloc-rs" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d43ff92911d7d9705d1c0203300a3edfd00d16c8b8b0c27c56f9407a3f31e7a6" +dependencies = [ + "snmalloc-sys", +] + +[[package]] +name = "snmalloc-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "954e1f984860770475196be81a547ed1517d34fcb8a15cb87bdb37cff3353230" +dependencies = [ + "cmake", +] + [[package]] name = "strsim" version = "0.9.3" diff --git a/Cargo.toml b/Cargo.toml index 0ae3bef..89c31ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ clap = { version = "4.4", features = ["derive", "cargo"] } clap-verbosity-flag = "2.1.1" which = "6.0.1" simd-json = "0.14.3" -mimalloc = "0.1.43" +snmalloc-rs = { version = "0.3.7", features = ["native-cpu"] } [[example]] name = "native-json-parser" diff --git a/src/main.rs b/src/main.rs index a67a8bd..127cae9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,10 +4,9 @@ use clap::Parser; use emacs_lsp_booster::app; use emacs_lsp_booster::bytecode; -use mimalloc::MiMalloc; #[global_allocator] -static GLOBAL: MiMalloc = MiMalloc; +static ALLOC: snmalloc_rs::SnMalloc = snmalloc_rs::SnMalloc; #[derive(Parser)] From f249189e43ec3c635bc04e7e79c7e4d33163f64a Mon Sep 17 00:00:00 2001 From: WSRer <1749094641@qq.com> Date: Mon, 20 Jan 2025 10:23:26 +0800 Subject: [PATCH 4/5] use mimalloc --- Cargo.lock | 48 ++++++++++++++++++++---------------------------- Cargo.toml | 2 +- src/main.rs | 5 +++-- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f370b4..0f3ab41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,15 +172,6 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" -[[package]] -name = "cmake" -version = "0.1.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" -dependencies = [ - "cc", -] - [[package]] name = "colorchoice" version = "1.0.0" @@ -264,11 +255,11 @@ dependencies = [ "env_logger", "lazy_static", "log", + "mimalloc", "serde", "serde_json", "simd-json", "smallvec", - "snmalloc-rs", "tempfile", "which", ] @@ -439,6 +430,16 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libmimalloc-sys" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -457,6 +458,15 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "mimalloc" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" +dependencies = [ + "libmimalloc-sys", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -655,24 +665,6 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" -[[package]] -name = "snmalloc-rs" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d43ff92911d7d9705d1c0203300a3edfd00d16c8b8b0c27c56f9407a3f31e7a6" -dependencies = [ - "snmalloc-sys", -] - -[[package]] -name = "snmalloc-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "954e1f984860770475196be81a547ed1517d34fcb8a15cb87bdb37cff3353230" -dependencies = [ - "cmake", -] - [[package]] name = "strsim" version = "0.9.3" diff --git a/Cargo.toml b/Cargo.toml index 6a92aab..4bbb23a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ clap = { version = "4.4", features = ["derive", "cargo"] } clap-verbosity-flag = "2.1.1" which = "6.0.1" simd-json = "0.14.3" -snmalloc-rs = { version = "0.3.7", features = ["native-cpu"] } +mimalloc = "0.1.43" [[example]] name = "native-json-parser" diff --git a/src/main.rs b/src/main.rs index 127cae9..d1e6212 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,9 +5,10 @@ use clap::Parser; use emacs_lsp_booster::app; use emacs_lsp_booster::bytecode; -#[global_allocator] -static ALLOC: snmalloc_rs::SnMalloc = snmalloc_rs::SnMalloc; +use mimalloc::MiMalloc; +#[global_allocator] +static GLOBAL: MiMalloc = MiMalloc; #[derive(Parser)] #[command(long_about = None, about = None, From 279c0966180605afdb54290b3fc2671b05eb7cc2 Mon Sep 17 00:00:00 2001 From: WSRer <69560752+nanakura@users.noreply.github.com> Date: Tue, 21 Jan 2025 20:58:39 +0800 Subject: [PATCH 5/5] profile optimize --- Cargo.toml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 4bbb23a..5473111 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,15 @@ crate-type = ["cdylib"] [dev-dependencies] emacs = "0.18" tempfile = "3.9" + +[profile.release] +opt-level = 3 +lto = "thin" +codegen-units = 1 +panic = "unwind" +debug = false +overflow-checks = false +strip = false + +[profile.release.package."*"] +opt-level = 3