-
Notifications
You must be signed in to change notification settings - Fork 0
β‘ Bolt: Optimize list literal evaluation #337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5746,6 +5746,7 @@ impl Interpreter { | |
| fn evaluate_literal_direct( | ||
| &self, | ||
| literal: &Literal, | ||
| env: &Rc<RefCell<Environment>>, | ||
| line: usize, | ||
| column: usize, | ||
| ) -> Result<Option<Value>, RuntimeError> { | ||
|
|
@@ -5761,8 +5762,20 @@ impl Interpreter { | |
| line, | ||
| column, | ||
| )), | ||
| // List requires recursion, so fall through to boxed implementation | ||
| Literal::List(_) => Ok(None), | ||
| Literal::List(elements) => { | ||
| let mut list_values = Vec::with_capacity(elements.len()); | ||
| for element in elements { | ||
| // Recursively try to evaluate elements synchronously. | ||
| // This works for nested lists as well. | ||
| if let Some(value) = self.try_evaluate_simple_expr_sync(element, env)? { | ||
| list_values.push(value); | ||
| } else { | ||
| // Element requires async evaluation, abort sync optimization for the whole list | ||
| return Ok(None); | ||
| } | ||
| } | ||
|
Comment on lines
+5766
to
+5776
|
||
| Ok(Some(Value::List(Rc::new(RefCell::new(list_values))))) | ||
| } | ||
|
Comment on lines
+5765
to
+5778
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid double-evaluation when list sync path falls back to async. If an element later in the list requires async evaluation, the fast-path returns π€ Prompt for AI Agents |
||
| } | ||
| } | ||
|
|
||
|
|
@@ -5807,7 +5820,7 @@ impl Interpreter { | |
| ) -> Result<Option<Value>, RuntimeError> { | ||
| match expr { | ||
| Expression::Literal(literal, line, column) => { | ||
| self.evaluate_literal_direct(literal, *line, *column) | ||
| self.evaluate_literal_direct(literal, env, *line, *column) | ||
| } | ||
| Expression::Variable(name, line, column) => { | ||
| self.try_evaluate_variable_sync(name, env, *line, *column) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
Literal::Listfast path evaluates each element immediately and only returnsNonewhen it later encounters a non-sync expression, which causesevaluate_expressionto re-run the entire list in_evaluate_expression. In mixed lists (for example[random, some_call(...)]whererandomis auto-called as a zero-arg native function), earlier elements are executed twice, changing observable behavior (extra RNG/time calls or other side effects) compared to the previous single evaluation path.Useful? React with πΒ / π.