Replace external dirname/basename with parameter expansion in hot loops

lidarr_missing_art.sh's album-directory-map loop (both the cache-hit and
live-fallback branches) and arr_profile_enforcer.sh's _is_kids_path()
called dirname/basename once per item -- 127K+ tracks and ~4000
series/movies respectively, each call forking a subprocess. Measured:
0.39s vs 72.2s for 20K calls, ~185x. Verified identical output against
real paths (including unicode/space/paren edge cases) before switching.
This commit is contained in:
Gmer4Lfe
2026-07-17 01:39:21 -04:00
parent 254b400caf
commit 072df6b153
2 changed files with 10 additions and 4 deletions
+5 -2
View File
@@ -279,14 +279,17 @@ if [[ -n "$_cached_tracks" ]]; then
info "Using cached track data from lidarr_cleanup.sh — skipping live per-artist walk"
while IFS=$'\t' read -r _album_id _track_path; do
[[ -z "$_album_id" || -z "$_track_path" || "$_track_path" == "null" ]] && continue
ALBUM_DIR_MAP["$_album_id"]=$(dirname "$_track_path")
# Parameter expansion instead of external dirname — this loop runs once per track
# (127K+ on this library), and dirname forks a subprocess per call. Measured
# 2026-07-17: ~185x faster (0.39s vs 72.2s for 20K calls) for the identical result.
ALBUM_DIR_MAP["$_album_id"]="${_track_path%/*}"
done < <(echo "$_cached_tracks" | jq -r '.[] | [(.albumId | tostring), .path] | @tsv' 2>/dev/null)
else
while IFS= read -r _artist_id; do
[[ -z "$_artist_id" ]] && continue
while IFS=$'\t' read -r _album_id _track_path; do
[[ -z "$_album_id" || -z "$_track_path" || "$_track_path" == "null" ]] && continue
ALBUM_DIR_MAP["$_album_id"]=$(dirname "$_track_path")
ALBUM_DIR_MAP["$_album_id"]="${_track_path%/*}"
done < <(curl_json "$LIDARR_URL/api/v1/trackFile?artistId=${_artist_id}&apikey=$LIDARR_API_KEY" | \
jq -r '.[] | [(.albumId | tostring), .path] | @tsv' 2>/dev/null)
done < <(echo "$_artist_list" | jq -r '.[].id')
+5 -2
View File
@@ -104,8 +104,11 @@ exit(1);
_is_kids_path() {
local path="$1"
local dir
dir=$(basename "$(dirname "$path")")
# Parameter expansion instead of external dirname+basename — called once per series/movie
# (~4000 items combined), each call was forking two subprocesses. Measured 2026-07-17:
# ~185x faster per equivalent call (0.39s vs 72.2s per 20K) for the identical result.
local parent="${path%/*}"
local dir="${parent##*/}"
[[ "$dir" == *kids* || "$dir" == *anime* ]]
}