From 4172d39f619dff08dc4dea8d2146306c3f06f2fc Mon Sep 17 00:00:00 2001 From: Taneli Hukkinen <3275109+hukkin@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:04:20 +0200 Subject: [PATCH] performance: Slightly faster line wrap --- pyproject.toml | 9 +++++++++ src/mdformat/renderer/_context.py | 7 +++---- tests/test_for_profiler.py | 2 ++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 00274a6..8400611 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -145,6 +145,15 @@ commands = [ ["python", "fuzzer/fuzz.py", "{toxworkdir}/fuzzer-corpus", { replace = "posargs", default = ["-len_control=10000"], extend = true }], ] +[tool.tox.env."benchmark"] +description = "benchmark mdformat against local doc files" +commands = [ + ["python", "-c", "print('Wrap mode: keep')"], + ["python", "-m", "timeit", "from mdformat._cli import run", 'run(["README.md", "docs/", "--check"])'], + ["python", "-c", "print('Wrap mode: 50')"], + ["python", "-m", "timeit", "from mdformat._cli import run", 'run(["README.md", "docs/", "--check", "--wrap", "50"])'], +] + [tool.coverage.run] source = ["mdformat"] diff --git a/src/mdformat/renderer/_context.py b/src/mdformat/renderer/_context.py index df67993..99e9796 100644 --- a/src/mdformat/renderer/_context.py +++ b/src/mdformat/renderer/_context.py @@ -40,6 +40,7 @@ # A marker used to indicate location of a character that should be preserved # during word wrap. Should be converted to the actual character after wrap. PRESERVE_CHAR = "\x00" +RE_PRESERVE_CHAR = re.compile(re.escape(PRESERVE_CHAR)) def make_render_children(separator: str) -> Render: @@ -372,10 +373,8 @@ def _prepare_wrap(text: str) -> tuple[str, str]: def _recover_preserve_chars(text: str, replacements: str) -> str: - replacement_iterator = iter(replacements) - return "".join( - next(replacement_iterator) if c == PRESERVE_CHAR else c for c in text - ) + iter_replacements = iter(replacements) + return RE_PRESERVE_CHAR.sub(lambda _: next(iter_replacements), text) def paragraph(node: RenderTreeNode, context: RenderContext) -> str: # noqa: C901 diff --git a/tests/test_for_profiler.py b/tests/test_for_profiler.py index 806e848..a7eb724 100644 --- a/tests/test_for_profiler.py +++ b/tests/test_for_profiler.py @@ -24,3 +24,5 @@ def test_for_profiler(): docs_path = PROJECT_ROOT / "docs" readme_path = PROJECT_ROOT / "README.md" assert run([str(docs_path), str(readme_path), "--check"]) == 0 + # Also profile --wrap=INT code + run([str(docs_path), str(readme_path), "--check", "--wrap", "50"])