From feff6de7d5b93f323f80e391eea738ecec9c7694 Mon Sep 17 00:00:00 2001 From: Nicolas Polomack Date: Tue, 18 Aug 2020 07:17:20 +0200 Subject: [PATCH] Added support for Small String Optimisation (SSO) --- Cargo.lock | 16 ++++++++++++++++ som-interpreter-bc/Cargo.toml | 3 +++ som-interpreter-bc/src/compiler.rs | 5 +++-- som-interpreter-bc/src/main.rs | 3 +-- som-interpreter-bc/src/primitives/double.rs | 4 +--- som-interpreter-bc/src/primitives/integer.rs | 7 ++++--- som-interpreter-bc/src/primitives/string.rs | 5 ++--- som-interpreter-bc/src/primitives/symbol.rs | 8 +++----- som-interpreter-bc/src/value.rs | 3 ++- 9 files changed, 35 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8db751a..cbc01b03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -205,6 +205,14 @@ dependencies = [ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "smartstring" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "som-core" version = "0.1.0" @@ -233,6 +241,7 @@ dependencies = [ "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smartstring 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "som-core 0.1.0", "som-lexer 0.1.0", "som-parser-symbols 0.1.0", @@ -264,6 +273,11 @@ dependencies = [ "som-parser-core 0.1.0", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "strsim" version = "0.8.0" @@ -394,6 +408,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +"checksum smartstring 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdec7d62192ad94e7b16d49856c007d81ae1cf541cd29b4c04b755df39fd80d" +"checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum structopt 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "863246aaf5ddd0d6928dfeb1a9ca65f505599e4e1b399935ef7e75107516b4ef" "checksum structopt-derive 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d239ca4b13aee7a2142e6795cbd69e457665ff8037aed33b3effdc430d2f927a" diff --git a/som-interpreter-bc/Cargo.toml b/som-interpreter-bc/Cargo.toml index b725b4c7..adf811de 100644 --- a/som-interpreter-bc/Cargo.toml +++ b/som-interpreter-bc/Cargo.toml @@ -29,3 +29,6 @@ num-traits = "0.2.11" # random numbers rand = "0.7.3" + +# small string optimisation +smartstring = "0.2.3" diff --git a/som-interpreter-bc/src/compiler.rs b/som-interpreter-bc/src/compiler.rs index be653d9c..109d19fa 100644 --- a/som-interpreter-bc/src/compiler.rs +++ b/som-interpreter-bc/src/compiler.rs @@ -7,6 +7,7 @@ use std::rc::{Rc, Weak}; use indexmap::{IndexMap, IndexSet}; use num_bigint::BigInt; +use smartstring::alias::String as SmallString; use som_core::ast; use som_core::bytecode::Bytecode; @@ -21,7 +22,7 @@ use crate::SOMRef; #[derive(Debug, Clone)] pub enum Literal { Symbol(Interned), - String(Rc), + String(SmallString), Double(f64), Integer(i64), BigInteger(BigInt), @@ -290,7 +291,7 @@ impl MethodCodegen for ast::Expression { ast::Literal::Symbol(val) => { Literal::Symbol(ctxt.intern_symbol(val.as_str())) } - ast::Literal::String(val) => Literal::String(Rc::new(val.clone())), + ast::Literal::String(val) => Literal::String(val.into()), ast::Literal::Double(val) => Literal::Double(*val), ast::Literal::Integer(val) => Literal::Integer(*val), ast::Literal::BigInteger(val) => Literal::BigInteger(val.parse().unwrap()), diff --git a/som-interpreter-bc/src/main.rs b/som-interpreter-bc/src/main.rs index 18592ec4..c02425ba 100644 --- a/som-interpreter-bc/src/main.rs +++ b/som-interpreter-bc/src/main.rs @@ -4,7 +4,6 @@ #![warn(missing_docs)] use std::path::PathBuf; -use std::rc::Rc; use anyhow::anyhow; use structopt::StructOpt; @@ -76,7 +75,7 @@ fn main() -> anyhow::Result<()> { let args = std::iter::once(String::from(file_stem)) .chain(opts.args.iter().cloned()) - .map(Rc::new) + .map(Into::into) .map(Value::String) .collect(); diff --git a/som-interpreter-bc/src/primitives/double.rs b/som-interpreter-bc/src/primitives/double.rs index 2368ae66..7269dd4d 100644 --- a/som-interpreter-bc/src/primitives/double.rs +++ b/som-interpreter-bc/src/primitives/double.rs @@ -1,5 +1,3 @@ -use std::rc::Rc; - use crate::interpreter::Interpreter; use crate::primitives::PrimitiveFn; use crate::universe::Universe; @@ -49,7 +47,7 @@ fn as_string(interpreter: &mut Interpreter, _: &mut Universe) { frame .borrow_mut() .stack - .push(Value::String(Rc::new(value.to_string()))); + .push(Value::String(value.to_string().into())); } fn as_integer(interpreter: &mut Interpreter, _: &mut Universe) { diff --git a/som-interpreter-bc/src/primitives/integer.rs b/som-interpreter-bc/src/primitives/integer.rs index 60b9a551..5e70624b 100644 --- a/som-interpreter-bc/src/primitives/integer.rs +++ b/som-interpreter-bc/src/primitives/integer.rs @@ -1,5 +1,3 @@ -use std::rc::Rc; - use num_bigint::{BigInt, Sign}; use num_traits::ToPrimitive; use rand::distributions::Uniform; @@ -71,7 +69,10 @@ fn as_string(interpreter: &mut Interpreter, _: &mut Universe) { }; { - frame.borrow_mut().stack.push(Value::String(Rc::new(value))); + frame + .borrow_mut() + .stack + .push(Value::String(value.to_string().into())); return; } } diff --git a/som-interpreter-bc/src/primitives/string.rs b/som-interpreter-bc/src/primitives/string.rs index 580f7f97..cf30077d 100644 --- a/som-interpreter-bc/src/primitives/string.rs +++ b/som-interpreter-bc/src/primitives/string.rs @@ -1,7 +1,6 @@ use std::collections::hash_map::DefaultHasher; use std::convert::TryFrom; use std::hash::Hasher; -use std::rc::Rc; use crate::interpreter::Interpreter; use crate::primitives::PrimitiveFn; @@ -144,7 +143,7 @@ fn concatenate(interpreter: &mut Interpreter, universe: &mut Universe) { frame .borrow_mut() .stack - .push(Value::String(Rc::new(format!("{}{}", s1, s2)))) + .push(Value::String(format!("{}{}", s1, s2).into())) } fn as_symbol(interpreter: &mut Interpreter, universe: &mut Universe) { @@ -196,7 +195,7 @@ fn prim_substring_from_to(interpreter: &mut Interpreter, universe: &mut Universe (_, _, _) => panic!("'{}': wrong types", SIGNATURE), }; - let string = Rc::new(value.chars().skip(from).take(to - from).collect()); + let string = value.chars().skip(from).take(to - from).collect(); frame.borrow_mut().stack.push(Value::String(string)) } diff --git a/som-interpreter-bc/src/primitives/symbol.rs b/som-interpreter-bc/src/primitives/symbol.rs index d7d2932c..d44eef4a 100644 --- a/som-interpreter-bc/src/primitives/symbol.rs +++ b/som-interpreter-bc/src/primitives/symbol.rs @@ -1,5 +1,3 @@ -use std::rc::Rc; - use crate::interpreter::Interpreter; use crate::primitives::PrimitiveFn; use crate::universe::Universe; @@ -15,9 +13,9 @@ fn as_string(interpreter: &mut Interpreter, universe: &mut Universe) { Value::Symbol(sym) => sym, ]); - frame.borrow_mut().stack.push(Value::String(Rc::new( - universe.lookup_symbol(sym).to_string(), - ))); + frame.borrow_mut().stack.push(Value::String( + universe.lookup_symbol(sym).to_string().into(), + )); } /// Search for a primitive matching the given signature. diff --git a/som-interpreter-bc/src/value.rs b/som-interpreter-bc/src/value.rs index 0fb2b582..6074df62 100644 --- a/som-interpreter-bc/src/value.rs +++ b/som-interpreter-bc/src/value.rs @@ -2,6 +2,7 @@ use std::fmt; use std::rc::Rc; use num_bigint::BigInt; +use smartstring::alias::String as SmallString; use crate::block::Block; use crate::class::Class; @@ -29,7 +30,7 @@ pub enum Value { /// An interned symbol value. Symbol(Interned), /// A string value. - String(Rc), + String(SmallString), /// An array of values. Array(SOMRef>), /// A block value, ready to be evaluated.