Skip to content

Commit

Permalink
Merge pull request #144 from schungx/master
Browse files Browse the repository at this point in the history
Packages and general speed increases (esp for arrays and maps)
  • Loading branch information
schungx committed Apr 29, 2020
2 parents a1ec35f + 21c3edb commit ec4b01d
Show file tree
Hide file tree
Showing 81 changed files with 3,878 additions and 2,990 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Expand Up @@ -33,7 +33,7 @@ only_i64 = [] # set INT=i64 (default) and disable support for all other in
sync = [] # restrict to only types that implement Send + Sync

# compiling for no-std
no_std = [ "num-traits/libm", "hashbrown", "core-error", "libm" ]
no_std = [ "num-traits/libm", "hashbrown", "core-error", "libm", "ahash" ]

# other developer features
no_stdlib = [] # do not register the standard library
Expand Down Expand Up @@ -63,4 +63,5 @@ optional = true
[dependencies.ahash]
version = "0.3.2"
default-features = false
features = ["compile-time-rng"]
optional = true
168 changes: 106 additions & 62 deletions README.md

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion benches/engine.rs
Expand Up @@ -16,14 +16,25 @@ fn bench_engine_new_raw(bench: &mut Bencher) {
bench.iter(|| Engine::new_raw());
}

#[bench]
fn bench_engine_new_raw_core(bench: &mut Bencher) {
use rhai::packages::*;
let package = CorePackage::new();

bench.iter(|| {
let mut engine = Engine::new_raw();
engine.load_package(package.get());
});
}

#[bench]
fn bench_engine_register_fn(bench: &mut Bencher) {
fn hello(a: INT, b: Array, c: Map) -> bool {
true
}

bench.iter(|| {
let mut engine = Engine::new();
let mut engine = Engine::new_raw();
engine.register_fn("hello", hello);
});
}
2 changes: 1 addition & 1 deletion benches/eval_array.rs
Expand Up @@ -51,7 +51,7 @@ fn bench_eval_array_large_set(bench: &mut Bencher) {
let script = r#"let x = [ 1, 2.345, "hello", true,
[ 1, 2, 3, [ "hey", [ "deeply", "nested" ], "jude" ] ]
];
x[4] = 42
x[4][3][1][1] = 42
"#;

let mut engine = Engine::new();
Expand Down
10 changes: 4 additions & 6 deletions benches/iterations.rs
Expand Up @@ -3,7 +3,7 @@
///! Test 1,000 iterations
extern crate test;

use rhai::{Engine, OptimizationLevel, Scope, INT};
use rhai::{Engine, OptimizationLevel, INT};
use test::Bencher;

#[bench]
Expand Down Expand Up @@ -34,16 +34,14 @@ fn bench_iterations_fibonacci(bench: &mut Bencher) {
fibonacci(n-1) + fibonacci(n-2)
}
}
fibonacci(20)
"#;

let mut engine = Engine::new();
engine.set_optimization_level(OptimizationLevel::None);

let ast = engine.compile(script).unwrap();

bench.iter(|| {
engine
.call_fn::<_, INT>(&mut Scope::new(), &ast, "fibonacci", (20 as INT,))
.unwrap()
});
bench.iter(|| engine.eval_ast::<INT>(&ast).unwrap());
}
3 changes: 2 additions & 1 deletion benches/parsing.rs
Expand Up @@ -74,7 +74,8 @@ fn bench_parse_primes(bench: &mut Bencher) {
let prime_mask = [];
prime_mask.pad(MAX_NUMBER_TO_CHECK, true);
prime_mask[0] = prime_mask[1] = false;
prime_mask[0] = false;
prime_mask[1] = false;
let total_primes_found = 0;
Expand Down
5 changes: 2 additions & 3 deletions benches/primes.rs
Expand Up @@ -9,14 +9,13 @@ use test::Bencher;
// This script uses the Sieve of Eratosthenes to calculate prime numbers.

const SCRIPT: &str = r#"
let now = timestamp();
const MAX_NUMBER_TO_CHECK = 1_000; // 168 primes <= 1000
let prime_mask = [];
prime_mask.pad(MAX_NUMBER_TO_CHECK, true);
prime_mask[0] = prime_mask[1] = false;
prime_mask[0] = false;
prime_mask[1] = false;
let total_primes_found = 0;
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_types_and_methods.rs
Expand Up @@ -16,7 +16,7 @@ impl TestStruct {
}

#[cfg(not(feature = "no_object"))]
fn main() -> Result<(), EvalAltResult> {
fn main() -> Result<(), Box<EvalAltResult>> {
let mut engine = Engine::new();

engine.register_type::<TestStruct>();
Expand Down
8 changes: 5 additions & 3 deletions examples/hello.rs
@@ -1,7 +1,9 @@
use rhai::{Engine, EvalAltResult, INT};
use rhai::{packages::*, Engine, EvalAltResult, INT};
use std::rc::Rc;

fn main() -> Result<(), EvalAltResult> {
let engine = Engine::new();
fn main() -> Result<(), Box<EvalAltResult>> {
let mut engine = Engine::new_raw();
engine.load_package(ArithmeticPackage::new().get());

let result = engine.eval::<INT>("40 + 2")?;

Expand Down
8 changes: 7 additions & 1 deletion examples/no_std.rs
Expand Up @@ -2,7 +2,13 @@

use rhai::{Engine, EvalAltResult, INT};

fn main() -> Result<(), EvalAltResult> {
#[cfg(feature = "no_std")]
extern crate alloc;

#[cfg(feature = "no_std")]
use alloc::boxed::Box;

fn main() -> Result<(), Box<EvalAltResult>> {
let engine = Engine::new();

let result = engine.eval::<INT>("40 + 2")?;
Expand Down
2 changes: 1 addition & 1 deletion examples/repl.rs
Expand Up @@ -157,7 +157,7 @@ fn main() {
Ok(_) => (),
Err(err) => {
println!();
print_error(&input, err);
print_error(&input, *err);
println!();
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/reuse_scope.rs
@@ -1,6 +1,6 @@
use rhai::{Engine, EvalAltResult, Scope, INT};

fn main() -> Result<(), EvalAltResult> {
fn main() -> Result<(), Box<EvalAltResult>> {
let engine = Engine::new();
let mut scope = Scope::new();

Expand Down
2 changes: 1 addition & 1 deletion examples/rhai_runner.rs
Expand Up @@ -72,7 +72,7 @@ fn main() {
eprintln!("{:=<1$}", "", filename.len());
eprintln!("");

eprint_error(&contents, err);
eprint_error(&contents, *err);
}
}
}
2 changes: 1 addition & 1 deletion examples/simple_fn.rs
@@ -1,6 +1,6 @@
use rhai::{Engine, EvalAltResult, RegisterFn, INT};

fn main() -> Result<(), EvalAltResult> {
fn main() -> Result<(), Box<EvalAltResult>> {
let mut engine = Engine::new();

fn add(x: INT, y: INT) -> INT {
Expand Down
8 changes: 2 additions & 6 deletions scripts/mat_mul.rhai
Expand Up @@ -16,9 +16,7 @@ fn mat_gen(n) {

for i in range(0, n) {
for j in range(0, n) {
let foo = m[i];
foo[j] = tmp * (i.to_float() - j.to_float()) * (i.to_float() + j.to_float());
m[i] = foo;
m[i][j] = tmp * (i.to_float() - j.to_float()) * (i.to_float() + j.to_float());
}
}

Expand All @@ -34,9 +32,7 @@ fn mat_mul(a, b) {

for i in range(0, n) {
for j in range(0, p) {
let foo = b2[j];
foo[i] = b[i][j];
b2[j] = foo;
b2[j][i] = b[i][j];
}
}

Expand Down
5 changes: 3 additions & 2 deletions scripts/primes.rhai
Expand Up @@ -2,12 +2,13 @@

let now = timestamp();

const MAX_NUMBER_TO_CHECK = 10_000; // 1229 primes <= 10000
const MAX_NUMBER_TO_CHECK = 100_000; // 9592 primes <= 100000

let prime_mask = [];
prime_mask.pad(MAX_NUMBER_TO_CHECK, true);

prime_mask[0] = prime_mask[1] = false;
prime_mask[0] = false;
prime_mask[1] = false;

let total_primes_found = 0;

Expand Down
74 changes: 49 additions & 25 deletions src/any.rs
Expand Up @@ -9,8 +9,10 @@ use crate::parser::FLOAT;
use crate::stdlib::{
any::{type_name, Any, TypeId},
boxed::Box,
collections::HashMap,
fmt,
string::String,
vec::Vec,
};

#[cfg(not(feature = "no_std"))]
Expand Down Expand Up @@ -65,6 +67,9 @@ impl<T: Any + Clone> Variant for T {
}

/// A trait to represent any type.
///
/// `From<_>` is implemented for `i64` (`i32` if `only_i32`), `f64` (if not `no_float`),
/// `bool`, `String`, `char`, `Vec<T>` (into `Array`) and `HashMap<String, T>` (into `Map`).
#[cfg(feature = "sync")]
pub trait Variant: Any + Send + Sync {
/// Convert this `Variant` trait object to `&dyn Any`.
Expand Down Expand Up @@ -207,7 +212,7 @@ impl fmt::Display for Dynamic {
#[cfg(not(feature = "no_float"))]
Union::Float(value) => write!(f, "{}", value),
Union::Array(value) => write!(f, "{:?}", value),
Union::Map(value) => write!(f, "{:?}", value),
Union::Map(value) => write!(f, "#{:?}", value),
Union::Variant(_) => write!(f, "?"),
}
}
Expand All @@ -224,7 +229,7 @@ impl fmt::Debug for Dynamic {
#[cfg(not(feature = "no_float"))]
Union::Float(value) => write!(f, "{:?}", value),
Union::Array(value) => write!(f, "{:?}", value),
Union::Map(value) => write!(f, "{:?}", value),
Union::Map(value) => write!(f, "#{:?}", value),
Union::Variant(_) => write!(f, "<dynamic>"),
}
}
Expand Down Expand Up @@ -263,16 +268,6 @@ fn cast_box<X: Variant, T: Variant>(item: Box<X>) -> Result<T, Box<X>> {
}

impl Dynamic {
/// Get a reference to the inner `Union`.
pub(crate) fn get_ref(&self) -> &Union {
&self.0
}

/// Get a mutable reference to the inner `Union`.
pub(crate) fn get_mut(&mut self) -> &mut Union {
&mut self.0
}

/// Create a `Dynamic` from any type. A `Dynamic` value is simply returned as is.
///
/// Beware that you need to pass in an `Array` type for it to be recognized as an `Array`.
Expand Down Expand Up @@ -450,7 +445,7 @@ impl Dynamic {

/// Cast the `Dynamic` as the system integer type `INT` and return it.
/// Returns the name of the actual type if the cast fails.
pub(crate) fn as_int(&self) -> Result<INT, &'static str> {
pub fn as_int(&self) -> Result<INT, &'static str> {
match self.0 {
Union::Int(n) => Ok(n),
_ => Err(self.type_name()),
Expand All @@ -459,7 +454,7 @@ impl Dynamic {

/// Cast the `Dynamic` as a `bool` and return it.
/// Returns the name of the actual type if the cast fails.
pub(crate) fn as_bool(&self) -> Result<bool, &'static str> {
pub fn as_bool(&self) -> Result<bool, &'static str> {
match self.0 {
Union::Bool(b) => Ok(b),
_ => Err(self.type_name()),
Expand All @@ -468,7 +463,7 @@ impl Dynamic {

/// Cast the `Dynamic` as a `char` and return it.
/// Returns the name of the actual type if the cast fails.
pub(crate) fn as_char(&self) -> Result<char, &'static str> {
pub fn as_char(&self) -> Result<char, &'static str> {
match self.0 {
Union::Char(n) => Ok(n),
_ => Err(self.type_name()),
Expand All @@ -477,7 +472,7 @@ impl Dynamic {

/// Cast the `Dynamic` as a string and return the string slice.
/// Returns the name of the actual type if the cast fails.
pub(crate) fn as_str(&self) -> Result<&str, &'static str> {
pub fn as_str(&self) -> Result<&str, &'static str> {
match &self.0 {
Union::Str(s) => Ok(s),
_ => Err(self.type_name()),
Expand All @@ -486,33 +481,62 @@ impl Dynamic {

/// Convert the `Dynamic` into `String` and return it.
/// Returns the name of the actual type if the cast fails.
pub(crate) fn take_string(self) -> Result<String, &'static str> {
pub fn take_string(self) -> Result<String, &'static str> {
match self.0 {
Union::Str(s) => Ok(*s),
_ => Err(self.type_name()),
}
}
}

pub(crate) fn from_unit() -> Self {
Self(Union::Unit(()))
impl From<()> for Dynamic {
fn from(value: ()) -> Self {
Self(Union::Unit(value))
}
pub(crate) fn from_bool(value: bool) -> Self {
}
impl From<bool> for Dynamic {
fn from(value: bool) -> Self {
Self(Union::Bool(value))
}
pub(crate) fn from_int(value: INT) -> Self {
}
impl From<INT> for Dynamic {
fn from(value: INT) -> Self {
Self(Union::Int(value))
}
#[cfg(not(feature = "no_float"))]
pub(crate) fn from_float(value: FLOAT) -> Self {
}
#[cfg(not(feature = "no_float"))]
impl From<FLOAT> for Dynamic {
fn from(value: FLOAT) -> Self {
Self(Union::Float(value))
}
pub(crate) fn from_char(value: char) -> Self {
}
impl From<char> for Dynamic {
fn from(value: char) -> Self {
Self(Union::Char(value))
}
pub(crate) fn from_string(value: String) -> Self {
}
impl From<String> for Dynamic {
fn from(value: String) -> Self {
Self(Union::Str(Box::new(value)))
}
}
impl<T: Variant + Clone> From<Vec<T>> for Dynamic {
fn from(value: Vec<T>) -> Self {
Self(Union::Array(Box::new(
value.into_iter().map(Dynamic::from).collect(),
)))
}
}
impl<T: Variant + Clone> From<HashMap<String, T>> for Dynamic {
fn from(value: HashMap<String, T>) -> Self {
Self(Union::Map(Box::new(
value
.into_iter()
.map(|(k, v)| (k, Dynamic::from(v)))
.collect(),
)))
}
}

/// Private type which ensures that `rhai::Any` and `rhai::AnyExt` can only
/// be implemented by this crate.
Expand Down

0 comments on commit ec4b01d

Please sign in to comment.