# HG changeset patch # User Raphaël Gomès # Date 2024-02-22 14:11:26 # Node ID 3099f1c68afd2e813aa9b6e2bca6075bcff2a28d # Parent 7c6d0b9dde373b86a79f3f868dc3706f4a0f2f52 rust-index: remove one collect when converting back Turns out this is slightly faster. Sending the results back to Python is still the most costly (like 75% of the time) of the whole method, but it's about as fast as it can be now. hg perf::phases on mozilla-try-2023-03-22 before: 0.267114 after: 0.247101 diff --git a/rust/hg-cpython/src/revlog.rs b/rust/hg-cpython/src/revlog.rs --- a/rust/hg-cpython/src/revlog.rs +++ b/rust/hg-cpython/src/revlog.rs @@ -989,20 +989,15 @@ impl Index { // Ugly hack, but temporary const IDX_TO_PHASE_NUM: [usize; 4] = [1, 2, 32, 96]; let py_phase_maps = PyDict::new(py); - for (idx, roots) in phase_maps.iter().enumerate() { + for (idx, roots) in phase_maps.into_iter().enumerate() { let phase_num = IDX_TO_PHASE_NUM[idx].into_py_object(py); - // OPTIM too bad we have to collect here. At least, we could - // reuse the same Vec and allocate it with capacity at - // max(len(phase_maps) - let roots_vec: Vec = roots - .iter() - .map(|r| PyRevision::from(*r).into_py_object(py)) - .collect(); - py_phase_maps.set_item( - py, - phase_num, - PySet::new(py, roots_vec)?, - )?; + // This is a bit faster than collecting into a `Vec` and passing + // it to `PySet::new`. + let set = PySet::empty(py)?; + for rev in roots { + set.add(py, PyRevision::from(rev).into_py_object(py))?; + } + py_phase_maps.set_item(py, phase_num, set)?; } Ok(PyTuple::new( py,