Skip to content

Commit

Permalink
enhancement(stdlib): Add support for constant parameters to zip (#1160
Browse files Browse the repository at this point in the history
)

The benchmark records that this improves performance of the two-parameter case
(with both parameters constant) by about 60%, which implies a performance boost
of about 30% per parameter. In the single parameter case, the performance boost
is about 40%, but that is unlikely to ever actually be useful.
  • Loading branch information
bruceg authored Dec 2, 2024
1 parent 62f0b4f commit c8af70c
Showing 1 changed file with 31 additions and 6 deletions.
37 changes: 31 additions & 6 deletions src/stdlib/zip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,23 @@ impl Function for Zip {

fn compile(
&self,
_state: &TypeState,
state: &TypeState,
_ctx: &mut FunctionCompileContext,
arguments: ArgumentList,
) -> Compiled {
let array_0 = arguments.required("array_0");
let array_1 = arguments.optional("array_1");
let array_0 = ConstOrExpr::new(arguments.required("array_0"), state);
let array_1 = arguments
.optional("array_1")
.map(|a| ConstOrExpr::new(a, state));

Ok(ZipFn { array_0, array_1 }.as_expr())
}
}

#[derive(Debug, Clone)]
#[derive(Clone, Debug)]
struct ZipFn {
array_0: Box<dyn Expression>,
array_1: Option<Box<dyn Expression>>,
array_0: ConstOrExpr,
array_1: Option<ConstOrExpr>,
}

impl FunctionExpression for ZipFn {
Expand All @@ -100,6 +103,28 @@ impl FunctionExpression for ZipFn {
}
}

#[derive(Clone, Debug)]
enum ConstOrExpr {
Const(Value),
Expr(Box<dyn Expression>),
}

impl ConstOrExpr {
fn new(expr: Box<dyn Expression>, state: &TypeState) -> Self {
match expr.resolve_constant(state) {
Some(cnst) => Self::Const(cnst),
None => Self::Expr(expr),
}
}

fn resolve(&self, ctx: &mut Context) -> Resolved {
match self {
Self::Const(value) => Ok(value.clone()),
Self::Expr(expr) => expr.resolve(ctx),
}
}
}

#[cfg(test)]
mod tests {
use crate::value;
Expand Down

0 comments on commit c8af70c

Please sign in to comment.