Make for loops for efficient.
This commit is contained in:
parent
97900320e1
commit
e3aa2c19ce
26
scripts/for3.rhai
Normal file
26
scripts/for3.rhai
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const MAX = 100;
|
||||||
|
const CHECK = ((MAX - 1) ** 2) * MAX;
|
||||||
|
|
||||||
|
print("Ready... Go!");
|
||||||
|
|
||||||
|
let now = timestamp();
|
||||||
|
|
||||||
|
print(`Creating ${MAX} closures...`);
|
||||||
|
|
||||||
|
let list = [];
|
||||||
|
|
||||||
|
for i in 0..MAX {
|
||||||
|
list.push(|| i ** 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
print(`Time = ${now.elapsed} seconds...`);
|
||||||
|
print(`Summing ${MAX} closures...`);
|
||||||
|
|
||||||
|
let sum = 0;
|
||||||
|
|
||||||
|
for f in list {
|
||||||
|
sum += f.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
print(`Sum = ${sum} (should be ${CHECK})`);
|
||||||
|
print(`Finished. Total run time = ${now.elapsed} seconds.`);
|
@ -2892,16 +2892,18 @@ impl Engine {
|
|||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
// Add the loop variables
|
// Add the loop variables
|
||||||
let orig_scope_len = scope.len();
|
let orig_scope_len = scope.len();
|
||||||
let counter_index = counter.as_ref().map(|Ident { name, .. }| {
|
let counter_index = if let Some(counter) = counter {
|
||||||
scope.push(unsafe_cast_var_name_to_lifetime(name), 0 as INT);
|
scope.push(unsafe_cast_var_name_to_lifetime(&counter.name), 0 as INT);
|
||||||
scope.len() - 1
|
scope.len() - 1
|
||||||
});
|
} else {
|
||||||
|
usize::MAX
|
||||||
|
};
|
||||||
scope.push(unsafe_cast_var_name_to_lifetime(name), ());
|
scope.push(unsafe_cast_var_name_to_lifetime(name), ());
|
||||||
let index = scope.len() - 1;
|
let index = scope.len() - 1;
|
||||||
|
|
||||||
for (x, iter_value) in func(iter_obj).enumerate() {
|
for (x, iter_value) in func(iter_obj).enumerate() {
|
||||||
// Increment counter
|
// Increment counter
|
||||||
if let Some(c) = counter_index {
|
if counter_index < usize::MAX {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
if x > INT::MAX as usize {
|
if x > INT::MAX as usize {
|
||||||
return Err(ERR::ErrorArithmetic(
|
return Err(ERR::ErrorArithmetic(
|
||||||
@ -2911,27 +2913,38 @@ impl Engine {
|
|||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut counter_var = scope
|
let index_value = (x as INT).into();
|
||||||
.get_mut_by_index(c)
|
|
||||||
.write_lock::<INT>()
|
#[cfg(not(feature = "no_closure"))]
|
||||||
.expect("`INT`");
|
{
|
||||||
*counter_var = x as INT;
|
let index_var = scope.get_mut_by_index(counter_index);
|
||||||
|
if index_var.is_shared() {
|
||||||
|
*index_var.write_lock().expect("`Dynamic`") = index_value;
|
||||||
|
} else {
|
||||||
|
*index_var = index_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "no_closure")]
|
||||||
|
{
|
||||||
|
*scope.get_mut_by_index(counter_index) = index_value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let loop_var = scope.get_mut_by_index(index);
|
|
||||||
let value = iter_value.flatten();
|
let value = iter_value.flatten();
|
||||||
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
let loop_var_is_shared = loop_var.is_shared();
|
{
|
||||||
#[cfg(feature = "no_closure")]
|
let loop_var = scope.get_mut_by_index(index);
|
||||||
let loop_var_is_shared = false;
|
if loop_var.is_shared() {
|
||||||
|
*loop_var.write_lock().expect("`Dynamic`") = value;
|
||||||
if loop_var_is_shared {
|
|
||||||
let mut value_ref = loop_var.write_lock().expect("`Dynamic`");
|
|
||||||
*value_ref = value;
|
|
||||||
} else {
|
} else {
|
||||||
*loop_var = value;
|
*loop_var = value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "no_closure")]
|
||||||
|
{
|
||||||
|
*scope.get_mut_by_index(index) = value;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
self.inc_operations(&mut global.num_operations, statements.position())?;
|
self.inc_operations(&mut global.num_operations, statements.position())?;
|
||||||
|
28
tests/for.rs
28
tests/for.rs
@ -371,3 +371,31 @@ fn test_for_module_iterator() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(not(feature = "no_closure"))]
|
||||||
|
fn test_for_capture() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let engine = Engine::new();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<INT>(
|
||||||
|
"
|
||||||
|
let a = [];
|
||||||
|
|
||||||
|
for (x, i) in 100..110 {
|
||||||
|
a += || i + x;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sum = 0;
|
||||||
|
|
||||||
|
for fp in a {
|
||||||
|
sum += fp.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
1180
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user