git.delta.rocks / jrsonnet / refs/commits / a52e5086a89b

difftreelog

perf reserve for large comps

xkwyswmsYaroslav Bolyukin2026-04-25parent: #364fdf9.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
111pub fn evaluate_comp(111pub fn evaluate_comp(
112 ctx: Context,112 ctx: Context,
113 specs: &[CompSpec],113 specs: &[CompSpec],
114 mut guaranteed_reserve: usize,
114 callback: &mut impl FnMut(Context) -> Result<()>,115 callback: &mut impl FnMut(Context, usize) -> Result<()>,
115) -> Result<()> {116) -> Result<()> {
116 match specs.first() {117 match specs.first() {
117 None => callback(ctx)?,118 None => callback(ctx, guaranteed_reserve)?,
118 Some(CompSpec::IfSpec(IfSpecData { cond, span: _ })) => {119 Some(CompSpec::IfSpec(IfSpecData { cond, span: _ })) => {
119 if bool::from_untyped(evaluate(ctx.clone(), cond)?)? {120 if bool::from_untyped(evaluate(ctx.clone(), cond)?)? {
120 evaluate_comp(ctx, &specs[1..], callback)?;121 evaluate_comp(ctx, &specs[1..], 0, callback)?;
121 }122 }
122 }123 }
123 Some(CompSpec::ForSpec(ForSpecData {124 Some(CompSpec::ForSpec(ForSpecData {
126 })) => {127 })) => {
127 match evaluate(ctx.clone(), over)? {128 match evaluate(ctx.clone(), over)? {
128 Val::Arr(list) => {129 Val::Arr(list) => {
130 guaranteed_reserve = guaranteed_reserve.max(1) * list.len();
129 for item in list.iter_lazy() {131 for (i, item) in list.iter_lazy().enumerate() {
130 let fctx = Pending::new();132 let fctx = Pending::new();
131 let mut new_bindings = FxHashMap::with_capacity(into.binds_len());133 let mut new_bindings = FxHashMap::with_capacity(into.binds_len());
132 destruct(into, item, fctx.clone(), &mut new_bindings)?;134 destruct(into, item, fctx.clone(), &mut new_bindings)?;
133 let ctx = ctx.clone().extend_bindings(new_bindings).into_future(fctx);135 let ctx = ctx.clone().extend_bindings(new_bindings).into_future(fctx);
134136
137 let specs = &specs[1..];
135 evaluate_comp(ctx, &specs[1..], callback)?;138 evaluate_comp(
139 ctx,
140 specs,
141 if i == 0 || !specs.is_empty() {
142 guaranteed_reserve
143 } else {
144 0
145 },
146 callback,
147 )?;
136 }148 }
137 }149 }
364 builder.with_super(super_obj);376 builder.with_super(super_obj);
365 }377 }
366 let locals = obj.locals.clone();378 let locals = obj.locals.clone();
367 evaluate_comp(ctx, &obj.compspecs, &mut |ctx| {379 evaluate_comp(ctx, &obj.compspecs, 0, &mut |ctx, reserve| {
368 let uctx = evaluate_object_locals(ctx.clone(), locals.clone());380 let uctx = evaluate_object_locals(ctx.clone(), locals.clone());
381 builder.reserve_cores(reserve);
369382
370 evaluate_field_member(&mut builder, ctx, uctx, &obj.field)383 evaluate_field_member(&mut builder, ctx, uctx, &obj.field)
371 })?;384 })?;
635 }648 }
636 ArrComp(expr, comp_specs) => {649 ArrComp(expr, comp_specs) => {
637 let mut out = Vec::new();650 let mut out = Vec::new();
638 evaluate_comp(ctx, comp_specs, &mut |ctx| {651 evaluate_comp(ctx, comp_specs, 0, &mut |ctx, reserve| {
652 if reserve != 0 {
653 out.reserve(reserve);
654 }
639 let expr = expr.clone();655 let expr = expr.clone();
640 out.push(Thunk!(move || evaluate(ctx, &expr)));656 out.push(Thunk!(move || evaluate(ctx, &expr)));
641 Ok(())657 Ok(())
modifiedcrates/jrsonnet-evaluator/src/obj/oop.rsdiffbeforeafterboth
135 next_field_index: FieldIndex::default(),135 next_field_index: FieldIndex::default(),
136 }136 }
137 }137 }
138 pub fn reserve_fields(&mut self, capacity: usize) {
139 self.new.this_entries.reserve(capacity);
140 }
138 pub fn reserve_cores(&mut self, capacity: usize) -> &mut Self {141 pub fn reserve_cores(&mut self, capacity: usize) -> &mut Self {
139 self.sup.reserve_exact(capacity);142 self.sup.reserve_exact(capacity);
140 self143 self