I wrote a script that renames a lot of files (tens of thousands). Performance was kind of slow (over 50 s), but with two changes it now runs at under 3 seconds, a 20x speed boost. Thought I'd share, in case it helps anyone else. These tips are good if you do things thousands of time in a script, I don't think they are relevant in all scripts.
Don't spawn sub shells if you can avoid it
Instead of command substitution with printf:
new_file="$(printf "%s/%s_%.${len}d.%s" "$new_dir" "$prefix" "$i" "$ext")"
do:
printf -v new_file "%s/%s_%.${len}d.%s" "$new_dir" "$prefix" "$i" "$ext"
This will save a sub shell.
Use builtins instead of external programs
Bash has optional builtins that you can enable. On my system they are located in /usr/lib/bash . You can enable them in your script by using enable <builtin>. Be sure to check the exit code. On my system a mv builtin is not available, but since I was renaming on the same file system I figured I could use ln and rm instead.
So instead of using external mv for each file I did:
builtin ln "$old_file" "$new_file" && builtin rm "$old_file"
In this case the builtin probably isn't required since builtins are prioritized over external commands, but I used them to be more explicit. Just be sure to use && so that rm never runs unless the hard link has been successfully created.