为何同功能Bash素数判断代码运行速度远慢于C++代码?
First, let's cut to the core of this issue: Bash is an interpreted shell language built for scripting and workflow automation, not heavy computational tasks, while C++ is a compiled language that gets converted directly to efficient machine code. The massive performance gap you're seeing isn't just about syntax—it's rooted in how each language executes operations, especially the repeated calculations in your loop.
The Biggest Bottlenecks in Your Original Bash Script
Your script relies heavily on the expr command, which creates a brand new subprocess every single time you call it. For a number like 1000000007, your loop runs roughly 5700 times, and each iteration calls expr 4 times. That's over 22,000 separate subprocesses—each one adds overhead for process creation, execution, and cleanup, which absolutely tanks performance.
On top of that, your loop condition uses a messy mix of expr and Bash arithmetic expansion ($((...))), adding unnecessary layers of processing that slow things down even more.
Optimized Bash Script (No More expr Overhead)
Let's rewrite the script using Bash's built-in arithmetic operations (((...))), which run directly in the shell without spawning subprocesses. This will drastically speed up execution:
read num f=1 if (( num == 2 || num == 3 )); then f=1 elif (( num % 2 == 0 || num % 3 == 0 )); then f=0 else for (( i=1; ; i++ )); do t=$((6*i - 1)) if (( t*t > num )); then break fi if (( num % t == 0 || num % (t+2) == 0 )); then f=0 break # Exit early once we find a divisor to save time fi done fi if (( f == 1 )); then echo 'Prime' else echo 'Not-Prime' fi
Key improvements:
- Replaced all
exprcalls with Bash's native arithmetic expansion ($((...))), which runs in-process with zero subprocess overhead. - Added an early
breakin the loop as soon as a divisor is found, avoiding unnecessary iterations. - Simplified the loop termination condition to check
t*t > numdirectly instead of recalculating it in the loop header.
Performance After Optimization
- Your C++ code still runs in ~0.003s (as expected for compiled machine code)
- The optimized Bash script will handle
1000000007in a few hundred milliseconds instead of hanging for 8+ seconds before you interrupt it.
Final Thoughts
Bash will never match C++ for computational speed—it's not designed for that. But for shell-based tasks, avoiding subprocesses (like expr, awk, or sed when built-ins work) is critical for decent performance. If you need to handle heavy number crunching in a shell environment, consider using a faster interpreted language like Python, or stick with compiled languages like C++ when speed is a priority.
内容的提问来源于stack exchange,提问作者Arshdeep Singh

