changeset 51426:3099f1c68afd

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
author Raphaël Gomès <rgomes@octobus.net>
date Thu, 22 Feb 2024 15:11:26 +0100
parents 7c6d0b9dde37
children d361d7bfb7dc
files rust/hg-cpython/src/revlog.rs
diffstat 1 files changed, 8 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/rust/hg-cpython/src/revlog.rs	Thu Feb 22 15:06:16 2024 +0100
+++ b/rust/hg-cpython/src/revlog.rs	Thu Feb 22 15:11:26 2024 +0100
@@ -989,20 +989,15 @@
         // 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<PyInt> = 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,