Skip to content

Commit f79eba0

Browse files
committed
speed up recur a little
1 parent 328dcd6 commit f79eba0

File tree

3 files changed

+40
-22
lines changed

3 files changed

+40
-22
lines changed

src/algorithm/pervade.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ use std::{
77

88
use ecow::eco_vec;
99

10-
use crate::algorithm::validate_size;
11-
use crate::fill::FillValue;
12-
use crate::{algorithm::loops::flip, array::*, Uiua, UiuaError, UiuaResult, Value};
13-
use crate::{Complex, Shape};
10+
use crate::{
11+
algorithm::{loops::flip, validate_size},
12+
array::*,
13+
fill::FillValue,
14+
Complex, Shape, Uiua, UiuaError, UiuaResult, Value,
15+
};
1416

1517
use super::{multi_output, FillContext, MultiOutput};
1618

src/algorithm/recur.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{SigNode, Uiua, UiuaResult, Value};
1+
use crate::{Primitive, SigNode, Uiua, UiuaResult, Value};
22

33
pub fn recur(is_leaf: SigNode, children: SigNode, combine: SigNode, env: &mut Uiua) -> UiuaResult {
44
// Signature validation
@@ -26,23 +26,27 @@ pub fn recur(is_leaf: SigNode, children: SigNode, combine: SigNode, env: &mut Ui
2626
children.sig
2727
)));
2828
}
29-
if combine.sig.args() == 0 {
30-
return Err(env.error(format!(
31-
"Combine function must have at least 1 argument, but its signature is {}",
32-
combine.sig
33-
)));
34-
}
35-
if combine.sig.outputs() != 1 {
36-
return Err(env.error(format!(
37-
"Combine function must have 1 output, but its signature is {}",
38-
combine.sig
39-
)));
29+
if combine.sig != (0, 0) {
30+
if combine.sig.args() == 0 {
31+
return Err(env.error(format!(
32+
"Combine function must have at least 1 argument, but its signature is {}",
33+
combine.sig
34+
)));
35+
}
36+
if combine.sig.outputs() != 1 {
37+
return Err(env.error(format!(
38+
"Combine function must have 1 output, but its signature is {}",
39+
combine.sig
40+
)));
41+
}
4042
}
43+
let call_combine =
44+
!(combine.node.is_empty() || combine.node.as_primitive() == Some(Primitive::Identity));
4145

4246
// State initialization
4347
let arg_count = (is_leaf.sig.args())
4448
.max(children.sig.args())
45-
.max(combine.sig.args() - 1);
49+
.max(combine.sig.args().saturating_sub(1));
4650
let const_count = arg_count - 1;
4751
let initial = env.pop(1)?;
4852
let mut consts = Vec::with_capacity(const_count);
@@ -99,12 +103,16 @@ pub fn recur(is_leaf: SigNode, children: SigNode, combine: SigNode, env: &mut Ui
99103
} else {
100104
Value::from_row_values(child_nodes, env)?
101105
};
102-
env.push(children_value);
103-
if combine.sig.args() > 1 {
104-
env.push(value);
106+
if call_combine {
107+
env.push(children_value);
108+
if combine.sig.args() > 1 {
109+
env.push(value);
110+
}
111+
env.exec(combine.clone())?;
112+
value = env.pop("combined")?;
113+
} else {
114+
value = children_value;
105115
}
106-
env.exec(combine.clone())?;
107-
value = env.pop("combined")?;
108116
if let Some(parent) = parent {
109117
stack[parent].child_nodes.as_mut().unwrap().push(value);
110118
} else {

tests/units.ua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,3 +743,11 @@ path(
743743
[[1_2 3_4 5_6] [7_8 9_10 11_12] [13_14 15_16 17_18]]
744744
⧋+ [100_200 300_400 500_600]
745745
⍤⤙≍ [[101_202 303_404 505_606] [107_208 309_410 511_612] [113_214 315_416 517_618]]
746+
747+
# Recur
748+
⍤⤙≍ 120 recur(<2|-1|×) 5
749+
⍤⤙≍ 5040 recur(<2|-1|×) 7
750+
⍤⤙≍ 55 recur(<2|⊃[-1|-2]|/+) 10
751+
⍤⤙≍ 89 recur(▽⊙1<2|⊃[-1|-2]|/+) 10
752+
⍤⤙≍ 1 recur<₂-₁∘ 5
753+
⍤⤙≍ 1 recur<₂-₁() 5

0 commit comments

Comments
 (0)