Refine immutable strings.
This commit is contained in:
parent
99ea2b33c9
commit
fca140ef55
@ -105,3 +105,54 @@ fn bench_eval_call(bench: &mut Bencher) {
|
|||||||
|
|
||||||
bench.iter(|| engine.eval::<bool>(script).unwrap());
|
bench.iter(|| engine.eval::<bool>(script).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_eval_loop_number(bench: &mut Bencher) {
|
||||||
|
let script = r#"
|
||||||
|
let s = 0;
|
||||||
|
for x in range(0, 10000) {
|
||||||
|
s += 1;
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
engine.set_optimization_level(OptimizationLevel::None);
|
||||||
|
|
||||||
|
let ast = engine.compile(script).unwrap();
|
||||||
|
|
||||||
|
bench.iter(|| engine.consume_ast(&ast).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_eval_loop_strings_build(bench: &mut Bencher) {
|
||||||
|
let script = r#"
|
||||||
|
let s = 0;
|
||||||
|
for x in range(0, 10000) {
|
||||||
|
s += "x";
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
engine.set_optimization_level(OptimizationLevel::None);
|
||||||
|
|
||||||
|
let ast = engine.compile(script).unwrap();
|
||||||
|
|
||||||
|
bench.iter(|| engine.consume_ast(&ast).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_eval_loop_strings_no_build(bench: &mut Bencher) {
|
||||||
|
let script = r#"
|
||||||
|
let s = "hello";
|
||||||
|
for x in range(0, 10000) {
|
||||||
|
s += "";
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
engine.set_optimization_level(OptimizationLevel::None);
|
||||||
|
|
||||||
|
let ast = engine.compile(script).unwrap();
|
||||||
|
|
||||||
|
bench.iter(|| engine.consume_ast(&ast).unwrap());
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Helper module which defines the `Any` trait to to allow dynamic value handling.
|
//! Helper module which defines the `Any` trait to to allow dynamic value handling.
|
||||||
|
|
||||||
|
use crate::fn_native::shared_unwrap;
|
||||||
use crate::parser::{ImmutableString, INT};
|
use crate::parser::{ImmutableString, INT};
|
||||||
use crate::r#unsafe::{unsafe_cast_box, unsafe_try_cast};
|
use crate::r#unsafe::{unsafe_cast_box, unsafe_try_cast};
|
||||||
|
|
||||||
@ -20,7 +21,9 @@ use crate::stdlib::{
|
|||||||
boxed::Box,
|
boxed::Box,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fmt,
|
fmt,
|
||||||
|
rc::Rc,
|
||||||
string::String,
|
string::String,
|
||||||
|
sync::Arc,
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -585,7 +588,7 @@ impl Dynamic {
|
|||||||
/// Returns the name of the actual type if the cast fails.
|
/// Returns the name of the actual type if the cast fails.
|
||||||
pub fn take_string(self) -> Result<String, &'static str> {
|
pub fn take_string(self) -> Result<String, &'static str> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Union::Str(s) => Ok((*s).clone()),
|
Union::Str(s) => Ok(shared_unwrap(s).unwrap_or_else(|s| (*s).clone())),
|
||||||
_ => Err(self.type_name()),
|
_ => Err(self.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1512,8 +1512,9 @@ impl Engine {
|
|||||||
|
|
||||||
let mut args: StaticVec<_> = arg_values.iter_mut().collect();
|
let mut args: StaticVec<_> = arg_values.iter_mut().collect();
|
||||||
|
|
||||||
if name == KEYWORD_EVAL && args.len() == 1 && args.get(0).is::<String>() {
|
if name == KEYWORD_EVAL && args.len() == 1 && args.get(0).is::<ImmutableString>() {
|
||||||
let hash_fn = calc_fn_hash(empty(), name, 1, once(TypeId::of::<String>()));
|
let hash_fn =
|
||||||
|
calc_fn_hash(empty(), name, 1, once(TypeId::of::<ImmutableString>()));
|
||||||
|
|
||||||
if !self.has_override(lib, (hash_fn, *hash)) {
|
if !self.has_override(lib, (hash_fn, *hash)) {
|
||||||
// eval - only in function call style
|
// eval - only in function call style
|
||||||
|
@ -19,6 +19,28 @@ pub type Shared<T> = Rc<T>;
|
|||||||
#[cfg(feature = "sync")]
|
#[cfg(feature = "sync")]
|
||||||
pub type Shared<T> = Arc<T>;
|
pub type Shared<T> = Arc<T>;
|
||||||
|
|
||||||
|
pub fn shared_make_mut<T: Clone>(value: &mut Shared<T>) -> &mut T {
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
|
{
|
||||||
|
Rc::make_mut(value)
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
{
|
||||||
|
Arc::make_mut(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shared_unwrap<T: Clone>(value: Shared<T>) -> Result<T, Shared<T>> {
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
|
{
|
||||||
|
Rc::try_unwrap(value)
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
{
|
||||||
|
Arc::try_unwrap(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type FnCallArgs<'a> = [&'a mut Dynamic];
|
pub type FnCallArgs<'a> = [&'a mut Dynamic];
|
||||||
|
|
||||||
#[cfg(not(feature = "sync"))]
|
#[cfg(not(feature = "sync"))]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
use crate::engine::{FUNC_TO_STRING, KEYWORD_DEBUG, KEYWORD_PRINT};
|
use crate::engine::{FUNC_TO_STRING, KEYWORD_DEBUG, KEYWORD_PRINT};
|
||||||
|
use crate::fn_native::shared_make_mut;
|
||||||
use crate::module::FuncReturn;
|
use crate::module::FuncReturn;
|
||||||
use crate::parser::{ImmutableString, INT};
|
use crate::parser::{ImmutableString, INT};
|
||||||
|
|
||||||
@ -41,8 +42,8 @@ def_package!(crate:BasicStringPackage:"Basic string utilities, including printin
|
|||||||
lib.set_fn_1(KEYWORD_PRINT, |_: ()| Ok("".to_string()));
|
lib.set_fn_1(KEYWORD_PRINT, |_: ()| Ok("".to_string()));
|
||||||
lib.set_fn_1(FUNC_TO_STRING, |_: ()| Ok("".to_string()));
|
lib.set_fn_1(FUNC_TO_STRING, |_: ()| Ok("".to_string()));
|
||||||
|
|
||||||
lib.set_fn_1(KEYWORD_PRINT, |s: ImmutableString| Ok(s.clone()));
|
lib.set_fn_1(KEYWORD_PRINT, |s: ImmutableString| Ok(s));
|
||||||
lib.set_fn_1(FUNC_TO_STRING, |s: ImmutableString| Ok(s.clone()));
|
lib.set_fn_1(FUNC_TO_STRING, |s: ImmutableString| Ok(s));
|
||||||
|
|
||||||
reg_op!(lib, KEYWORD_DEBUG, to_debug, INT, bool, (), char, ImmutableString);
|
reg_op!(lib, KEYWORD_DEBUG, to_debug, INT, bool, (), char, ImmutableString);
|
||||||
|
|
||||||
@ -81,6 +82,10 @@ def_package!(crate:BasicStringPackage:"Basic string utilities, including printin
|
|||||||
lib.set_fn_2(
|
lib.set_fn_2(
|
||||||
"+",
|
"+",
|
||||||
|s: ImmutableString, ch: char| {
|
|s: ImmutableString, ch: char| {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Ok(ch.to_string().into());
|
||||||
|
}
|
||||||
|
|
||||||
let mut s = (*s).clone();
|
let mut s = (*s).clone();
|
||||||
s.push(ch);
|
s.push(ch);
|
||||||
Ok(s)
|
Ok(s)
|
||||||
@ -89,23 +94,28 @@ def_package!(crate:BasicStringPackage:"Basic string utilities, including printin
|
|||||||
lib.set_fn_2(
|
lib.set_fn_2(
|
||||||
"+",
|
"+",
|
||||||
|s:ImmutableString, s2:ImmutableString| {
|
|s:ImmutableString, s2:ImmutableString| {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Ok(s2);
|
||||||
|
} else if s2.is_empty() {
|
||||||
|
return Ok(s);
|
||||||
|
}
|
||||||
|
|
||||||
let mut s = (*s).clone();
|
let mut s = (*s).clone();
|
||||||
s.push_str(s2.as_str());
|
s.push_str(s2.as_str());
|
||||||
Ok(s)
|
Ok(s.into())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
lib.set_fn_2_mut("append", |s: &mut ImmutableString, ch: char| {
|
lib.set_fn_2_mut("append", |s: &mut ImmutableString, ch: char| {
|
||||||
let mut copy = (**s).clone();
|
shared_make_mut(s).push(ch);
|
||||||
copy.push(ch);
|
|
||||||
*s = copy.into();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
lib.set_fn_2_mut(
|
lib.set_fn_2_mut(
|
||||||
"append",
|
"append",
|
||||||
|s: &mut ImmutableString, s2: ImmutableString| {
|
|s: &mut ImmutableString, s2: ImmutableString| {
|
||||||
let mut copy = (**s).clone();
|
if !s2.is_empty() {
|
||||||
copy.push_str(s2.as_str());
|
shared_make_mut(s).push_str(s2.as_str());
|
||||||
*s = copy.into();
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
|
use crate::fn_native::shared_make_mut;
|
||||||
use crate::module::FuncReturn;
|
use crate::module::FuncReturn;
|
||||||
use crate::parser::{ImmutableString, INT};
|
use crate::parser::{ImmutableString, INT};
|
||||||
use crate::utils::StaticVec;
|
use crate::utils::StaticVec;
|
||||||
@ -46,23 +47,19 @@ fn sub_string(s: ImmutableString, start: INT, len: INT) -> FuncReturn<ImmutableS
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
fn crop_string(s: &mut ImmutableString, start: INT, len: INT) -> FuncReturn<()> {
|
fn crop_string(s: &mut ImmutableString, start: INT, len: INT) -> FuncReturn<()> {
|
||||||
let mut copy = (**s).clone();
|
let offset = if s.is_empty() || len <= 0 {
|
||||||
|
shared_make_mut(s).clear();
|
||||||
let offset = if copy.is_empty() || len <= 0 {
|
|
||||||
copy.clear();
|
|
||||||
*s = copy.into();
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if start < 0 {
|
} else if start < 0 {
|
||||||
0
|
0
|
||||||
} else if (start as usize) >= copy.chars().count() {
|
} else if (start as usize) >= s.chars().count() {
|
||||||
copy.clear();
|
shared_make_mut(s).clear();
|
||||||
*s = copy.into();
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
start as usize
|
start as usize
|
||||||
};
|
};
|
||||||
|
|
||||||
let chars: StaticVec<_> = copy.chars().collect();
|
let chars: StaticVec<_> = s.chars().collect();
|
||||||
|
|
||||||
let len = if offset + (len as usize) > chars.len() {
|
let len = if offset + (len as usize) > chars.len() {
|
||||||
chars.len() - offset
|
chars.len() - offset
|
||||||
@ -70,12 +67,10 @@ fn crop_string(s: &mut ImmutableString, start: INT, len: INT) -> FuncReturn<()>
|
|||||||
len as usize
|
len as usize
|
||||||
};
|
};
|
||||||
|
|
||||||
*s = chars
|
let copy = shared_make_mut(s);
|
||||||
.iter()
|
copy.clear();
|
||||||
.skip(offset)
|
copy.extend(chars.iter().skip(offset).take(len));
|
||||||
.take(len)
|
|
||||||
.collect::<String>()
|
|
||||||
.into();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,21 +166,17 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
lib.set_fn_1_mut("clear", |s: &mut ImmutableString| {
|
lib.set_fn_1_mut("clear", |s: &mut ImmutableString| {
|
||||||
*s = "".to_string().into();
|
shared_make_mut(s).clear();
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
lib.set_fn_2_mut("append", |s: &mut ImmutableString, ch: char| {
|
lib.set_fn_2_mut("append", |s: &mut ImmutableString, ch: char| {
|
||||||
let mut copy = (**s).clone();
|
shared_make_mut(s).push(ch);
|
||||||
copy.push(ch);
|
|
||||||
*s = copy.into();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
lib.set_fn_2_mut(
|
lib.set_fn_2_mut(
|
||||||
"append",
|
"append",
|
||||||
|s: &mut ImmutableString, add: ImmutableString| {
|
|s: &mut ImmutableString, add: ImmutableString| {
|
||||||
let mut copy = (**s).clone();
|
shared_make_mut(s).push_str(add.as_str());
|
||||||
copy.push_str(add.as_str());
|
|
||||||
*s = copy.into();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -205,10 +196,13 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str
|
|||||||
lib.set_fn_2_mut(
|
lib.set_fn_2_mut(
|
||||||
"truncate",
|
"truncate",
|
||||||
|s: &mut ImmutableString, len: INT| {
|
|s: &mut ImmutableString, len: INT| {
|
||||||
if len >= 0 {
|
if len > 0 {
|
||||||
*s = (**s).clone().chars().take(len as usize).collect::<String>().into();
|
let chars: StaticVec<_> = s.chars().collect();
|
||||||
|
let copy = shared_make_mut(s);
|
||||||
|
copy.clear();
|
||||||
|
copy.extend(chars.into_iter().take(len as usize));
|
||||||
} else {
|
} else {
|
||||||
*s = "".to_string().into();
|
shared_make_mut(s).clear();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
@ -216,11 +210,10 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str
|
|||||||
lib.set_fn_3_mut(
|
lib.set_fn_3_mut(
|
||||||
"pad",
|
"pad",
|
||||||
|s: &mut ImmutableString, len: INT, ch: char| {
|
|s: &mut ImmutableString, len: INT, ch: char| {
|
||||||
let mut copy = (**s).clone();
|
let copy = shared_make_mut(s);
|
||||||
for _ in 0..copy.chars().count() - len as usize {
|
for _ in 0..copy.chars().count() - len as usize {
|
||||||
copy.push(ch);
|
copy.push(ch);
|
||||||
}
|
}
|
||||||
*s = copy.into();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user