fix: improve _is_excluded_line#192
Open
CarstenLeue wants to merge 1 commit into
Open
Conversation
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Added a 'pragma' not in line fast-path guard at the top of _is_excluded_line.
On any line that doesn't contain the word pragma (virtually every line in a normal repo), all 6 ALLOWLIST_REGEXES searches are skipped entirely and exclude_lines_regex is checked only if set.
The original slow path is reached only when pragma is actually present, preserving 100% of existing detection behaviour.
detect-secrets Performance Analysis
Profile date: Sun Jul 5 21:01:57 2026
Repository scanned:
bob4z-shell-proxyTotal runtime: 228.995 seconds (~3 min 49 s)
Total function calls: 118,548,394
Files scanned: 574
Executive Summary
Over 69% of all CPU time is consumed by a single operation: running 6 allowlist
regex patterns against every line of every file for every plugin. This is not secret
detection work — it is overhead checking whether a line carries a
# pragma: allowlist secretcomment. On a real repository where essentially no lines carry thatcomment, almost all of that cost is wasted.
Call-Tree Overview
Time Budget by Function
re.Pattern.searchre.Pattern.findallgetaddrinfo(version check)<genexpr>@ base.py:109base.py_io.open(file opens)builtins.anyanalyze_linebase.py:175analyzebase.py:120secret_generator(regex)base.py:425_is_excluded_linebase.py:107analyze_string_contentbase.py:410calculate_shannon_entropyhigh_entropy_strings.py:73Bottleneck 1 — Allowlist Regex Overhead (149 s, 65%)
Root cause
_is_excluded_lineindetect_secrets/plugins/base.py:107runs 6 compiled regexpatterns against every line of every file to detect an inline
# pragma: allowlist secretcomment:Why it is so expensive
reaches 4.7 million.
repository) all 6 regexes run to completion and return no match.
re.Pattern.searchcalls, virtually all of themfruitless.
any(genexpr)+builtins.anymachinery adds a further 33.2 million + 4.7million call-overhead frames.
Proportion of total work attributed to this path
re.Pattern.search(allowlist)<genexpr>driving the loopbuiltins.any_is_excluded_lineselfFix
A cheap
str.__contains__pre-filter eliminates the regex entirely on every ordinaryline. The word
pragmais present in every allowlist comment and absent fromessentially all other lines:
Expected impact: eliminates ~149 s (65% of total runtime). Estimated post-fix
runtime: ~50–70 s.
Bottleneck 2 — Plugin
findallfor Secret Detection (33 s, 15%)re.Pattern.findallis called 8.6 million times across all plugins for actual secretpattern matching (
RegexBasedDetector.secret_generator,KeywordDetector,HighEntropyStringsPlugin). This is legitimate work and cannot be removed, but it canbe reduced:
full pass of
findallper line per file. With 22 plugins, disabling 5 saves ~23%of this cost.
--base64-limit,--hex-limit) to reduce the numberof candidate strings that proceed to entropy calculation.
Bottleneck 3 — Version Check Network Call (8 s, 4%)
A single
getaddrinfocall at startup consumes 8.4 s — 100% of which is a DNS/TCPround-trip for the version check to PyPI. This is unrelated to scanning but adds fixed
overhead to every run.
Fix: pass
--no-version-checkon every invocation, or set it in the pre-commitconfig. Saves ~8–9 s unconditionally.
Bottleneck 4 —
calculate_shannon_entropy(1.2 s, 0.5%)Only 55,406 calls were made in this profile, making this negligible for this
repository. It would become relevant on repositories with many YAML/INI files
containing large quoted strings.
Findings Not Confirmed by This Profile
The following issues identified in static analysis did not appear as significant
costs in this specific repository:
Summary of Recommended Actions
pragmapre-filter to_is_excluded_line--no-version-check--no-<plugin>-scanconcurrent.futuresApplying P0 alone is expected to reduce the observed 229 s runtime to approximately
60–70 s with no change to detection behaviour.