8

我在 SPOJ 上解决了这个问题 - http://www.spoj.com/problems/ALICESIE/

问题归结为打印 (n+1)/2

这是我的 C 代码,在 0.03 秒内通过

    #include <stdio.h>
    int main() {
        int test, n;
        scanf("%d", &test);
        while(test--) {
            scanf("%d", &n);
            printf("%d\n", (n + 1) >> 1);
        }
        return 0;
    }

虽然这是我的 BASH 代码,它给出了 Time Limit Exceeded(即 > 1s)

read test
while (( test-- ))
do
    read n
    echo "$(((n+1)/2))"
done 

谁能让我知道为什么会这样?BASH 很慢吗?谢谢。

4

4 回答 4

5

Bash 在执行数字运算方面很慢。但这不是 Bash 的设计目的。

Bash 在编写脚本以自动执行某些重复操作方面非常快。修改错误的 Bash 脚本并再次运行它很快。可以快速找出 Bash 脚本到底在做什么(而不必寻找您正在查看的 C 可执行文件的源代码)。

而这样的例子不胜枚举。

C 和 Bash 是两种截然不同的语言和环境。如果你抱怨 Bash 很慢,那么你是在用它来解决错误的问题。

“不要抱怨螺丝刀很难把钉子钉在墙上。”

于 2013-04-12T15:20:51.160 回答
4

您正在将编译后的代码与脚本语言 (Bash) 进行比较。

Bash 脚本总是比编译后的代码慢,因为它们需要被解释。

您可能知道,为了运行用 C 编写的代码,您首先需要编译它。对于 Bash 脚本,您不必阅读它,代码只是“即时阅读”。所以 Bash 比 C 慢。

于 2013-04-12T15:12:18.420 回答
2

当然,由于其他答案中给出的原因,Bash 比 C 慢,但这并不能解释这里发生了什么。我怀疑你让你read的一个永远挂起,直到超时。当我实现这个时:

#!/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

不需要太多时间:

real    0m0.033s
user    0m0.029s
sys 0m0.013s

您可以使用 to标志强制read语句自行超时,如下所示:-tread

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
}
于 2013-04-12T15:25:57.443 回答
0

没有添加shebang。

#!/bin/bash

read test
while (( test-- ))
do
    read n
    echo "$(((n+1)/2))"
done 

我提交的这段代码在 SPOJ 中运行了 0.14 次并被接受。除了shebang之外,我看不到问题代码有任何区别!
(给读者)

于 2020-05-30T23:48:18.770 回答