rust/hg-cpython/src/update.rs
author Raphaël Gomès <rgomes@octobus.net>
Tue, 01 Oct 2024 13:49:11 +0200
changeset 52060 8b7123c8947b
permissions -rw-r--r--
update: add a Rust fast-path when updating from null (and clean) This case is easy to detect and we have all we need to generate a valid working copy and dirstate entirely in Rust, which speeds things up considerably: On my machine updating a repo of ~300k files goes from 10.00s down to 4.2s, all while consuming 50% less system time, with all caches hot. Something to note is that further improvements will probably happen with the upcoming `InnerRevlog` series that does smarter mmap hanlding, especially for filelogs. Here are benchmark numbers on a machine with only 4 cores (and no SMT enabled) ``` ### data-env-vars.name = heptapod-public-2024-03-25-ds2-pnm # benchmark.name = hg.command.update # bin-env-vars.hg.py-re2-module = default # bin-env-vars.hg.changeset.node = <this change> # benchmark.variants.atomic-update = no # benchmark.variants.scenario = null-to-tip # benchmark.variants.worker = default default: 5.328762 ~~~~~ rust: 1.308654 (-75.44%, -4.02) ### data-env-vars.name = mercurial-devel-2024-03-22-ds2-pnm # benchmark.name = hg.command.update # bin-env-vars.hg.py-re2-module = default # bin-env-vars.hg.changeset.node = <this change> # benchmark.variants.atomic-update = no # benchmark.variants.scenario = null-to-tip # benchmark.variants.worker = default default: 1.693271 ~~~~~ rust: 1.151053 (-32.02%, -0.54) ### data-env-vars.name = mozilla-unified-2024-03-22-ds2-pnm # benchmark.name = hg.command.update # bin-env-vars.hg.py-re2-module = default # bin-env-vars.hg.changeset.node = <this change> # benchmark.variants.atomic-update = no # benchmark.variants.scenario = null-to-tip # benchmark.variants.worker = default default: 38.901613 ~~~~~ rust: 11.637880 (-70.08%, -27.26) ### data-env-vars.name = netbsd-xsrc-public-2024-09-19-ds2-pnm # benchmark.name = hg.command.update # bin-env-vars.hg.py-re2-module = default # bin-env-vars.hg.changeset.node = <this change> # benchmark.variants.atomic-update = no # benchmark.variants.scenario = null-to-tip # benchmark.variants.worker = default default: 4.793727 ~~~~~ rust: 1.505905 (-68.59%, -3.29) ```
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52060
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     1
// debug.rs
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     2
//
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     3
// Copyright 2024 Mercurial developers
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     4
//
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     7
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     8
//! Module for updating a repository.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     9
use cpython::{PyDict, PyModule, PyObject, PyResult, Python};
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    10
use hg::{
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    11
    progress::{HgProgressBar, Progress},
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    12
    update::update_from_null,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    13
    BaseRevision,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    14
};
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    15
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    16
use crate::{
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    17
    exceptions::FallbackError,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    18
    utils::{hgerror_to_pyerr, repo_from_path},
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    19
};
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    20
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    21
pub fn update_from_null_fast_path(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    22
    py: Python,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    23
    repo_path: PyObject,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    24
    to: BaseRevision,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    25
) -> PyResult<usize> {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    26
    log::trace!("Using update from null fastpath");
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    27
    let repo = repo_from_path(py, repo_path)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    28
    let progress: &dyn Progress = &HgProgressBar::new("updating");
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    29
    hgerror_to_pyerr(py, update_from_null(&repo, to.into(), progress))
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    30
}
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    31
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    32
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    33
    let dotted_name = &format!("{}.update", package);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    34
    let m = PyModule::new(py, dotted_name)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    35
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    36
    m.add(py, "__package__", package)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
    m.add(py, "__doc__", "Rust module for updating a repository")?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    38
    m.add(py, "FallbackError", py.get_type::<FallbackError>())?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    39
    m.add(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    40
        py,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    41
        "update_from_null",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    42
        py_fn!(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    43
            py,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    44
            update_from_null_fast_path(repo_path: PyObject, to: BaseRevision,)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    45
        ),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    46
    )?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    47
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    48
    let sys = PyModule::import(py, "sys")?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    49
    let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    50
    sys_modules.set_item(py, dotted_name, &m)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    51
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    52
    Ok(m)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    53
}