8

私は SPOJ でこの質問を解決していました - http://www.spoj.com/problems/ALICESIE/

問題が要約すると (n+1)/2 を出力すること

これは 0.03 秒で渡される私の C コードです

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

これは Time Limit Exceeded (つまり > 1s ) を与える私の BASH コードですが、

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

なぜこれが起こっているのか誰にも教えてもらえますか?BASH は非常に遅いですか? ありがとう。

4

4 に答える 4

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 に答える