I was solving this question on SPOJ - http://www.spoj.com/problems/ALICESIE/
What the question boils down to print (n+1)/2
This is my C code which passes in 0.03s
#include <stdio.h>
int main() {
int test, n;
scanf("%d", &test);
while(test--) {
scanf("%d", &n);
printf("%d\n", (n + 1) >> 1);
}
return 0;
}
while this is my BASH code which gives Time Limit Exceeded ( i.e. > 1s )
read test
while (( test-- ))
do
read n
echo "$(((n+1)/2))"
done
Can anyone let me know why is this happening ? Is BASH very slow ? Thanks.
Shell loops are slow and bash's are the slowest. Shells aren't meant to do heavy work in loops. Shells are meant to launch a few external, optimized processes on batches of data.
Python is drastically faster on text processing, which is a common operation. If I perform the same search 10000 times on each language, on Bash it takes 1m24s, on Python 636ms. This is because Bash use a sub-process for each operation of the text processing, which is slow to create.
Python is faster than Bash and is ranked 1st, while Bash is ranked 34th. The most important reasons people chose Python are that it can be used for almost any task. It works on most major operating systems and is also installed by default on most Unix/Linus systems. It is very similar to writing pseudocode.
There are few ways to make your shell (eg Bash) execute faster. Try to use less of external commands if Bash's internals can do the task for you. Eg, excessive use of sed , grep , awk et for string/text manipulation. If you are manipulating relatively BIG files, don't use bash's while read loop.
Bash is slow in executing number-crunching. But that isn't what Bash was designed for.
Bash is very fast in whipping up a script for automating some repetitive action. It's fast to modify a faulty Bash script and run it again. It's fast to find out what exactly a Bash script is doing (as opposed to having to hunt down the source for the C executable you're looking at).
And the list goes on.
C and Bash are two very different breeds of languages and environments. If you complain about Bash being slow, you are using it for the wrong kind of problem.
"Do not complain that the screwdriver sucks at driving a nail into the wall."
You're comparing compiled code with a script language (Bash).
Bash scripts will always be slower than compiled code as they need to be interpreted.
As you probably know, in order to run your code written in C you first need to compile it. When it comes to Bash scripts, you don't have to read it, the code is just "read on the fly". So Bash is slower than C.
Bash is slower than C, for sure, because of the reasons given in other answers, but that doesn't explain what's happening here. I suspect you're letting one of your read
s hang forever, until timeout. When I implement this:
#!/bin/bash
main() {
local test
local i
local n
read test
for (( i=$test; i>0; i--)); do
read n
echo "$(((n+1)/2))"
done
}
time {
echo 1000
printf '%d\n' {1002..2}
} | main
It doesn't take very much time:
real 0m0.033s
user 0m0.029s
sys 0m0.013s
You can force the read
statements to time out on their own with the -t
flag to read
, like this:
main() {
local test
local i
local n
read -t.3 test
if [[ -z $test ]]; then
echo "Failed to read a test value within 300ms."
return 1
}
for (( i=$test; i>0; i--)); do
read -t.3 n
if [[ -z $n ]]; then
echo "Failed to read a value for n within 300ms."
return 1
}
echo "$(((n+1)/2))"
done
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With