1

数字の桁数を数える関数を書いてみたのですが、ちなみに別の方法の効率を比較してみました。1.lenstr(i) の方法:

def nDigits(i):
    return len(str(i))
for i in range(100000):
    print nDigits(i)

約143.75秒かかります

2.log10 の方法:

import math
def nDigits(i):
    if i > 0:
        n = int(math.log10(i)) + 1
    elif i == 0:
        n = 1
    else:
        n = int(math.log10(-i)) + 2
    return n

for i in range(100000):
    print nDigits(i)

約144.35秒かかります

3.分割方法:

def nDigits(i):
    t = 0
    while i > 0:
        t += 1
        i /= 10
    return t
for i in range(100000):
    print nDigits(i)

約143.43秒かかります

4.c の除算方法:

#include<stdio.h>

int digits(int num){
    int i = 0;
    while (num > 0){
        i += 1;
        num /= 10;
    }
    return i;
} 

void main(){
    int i = 0;
    while (i < 100000){
        i += 1;
        printf("%d",digits(i));    
    }
}

約0.07秒かかります

C は python より 2000 倍優れていますか... または python が桁数を数えるより良い方法があります。thx みんな、助けてください。

4

3 に答える 3

1

テストケースを簡素化し、それらをすべて削除しますprint

import math

def num_digits1(n):
    return len(str(n))

def num_digits2(n):
    return int(math.log10(n)) + 1

def num_digits3(n):
    t = 0

    while n:
        t += 1
        n /= 10

    return t

これが私の結果です:

>>> %timeit num_digits1(random.randint(1, 100000000))
100000 loops, best of 3: 1.64 us per loop
>>> %timeit num_digits2(random.randint(1, 100000000))
100000 loops, best of 3: 1.87 us per loop
>>> %timeit num_digits3(random.randint(1, 100000000))
100000 loops, best of 3: 2.49 us per loop
>>> %timeit random.randint(1, 100000000)
1000000 loops, best of 3: 1.29 us per loop

乱数の生成にかかる時間を差し引くと、次のようになります。

num_digits1  0.35 us
num_digits2  0.58 us
num_digits3  1.20 us

そして私のCコードの比較(私はそれが公正であることを願っています):

#include <stdlib.h>

int rand_int(int min, int max) {
    return min + (rand() / (double) RAND_MAX) / (max - min);
}

int num_digits(int num) {
    int i = 0;

    while (num > 0){
        i += 1;
        num /= 10;
    }

    return i;
} 

int main() {
    int i;

    for (i = 0; i < 10000000; i++) {
        num_digits(rand_int(1, 100000000));
    }

    return 0;
}

私はそれを実行します:

$ gcc test.c -o test
$ time ./test./test
0.15s user 0.00s system 97% cpu 0.154 total

そして私の時間は:

  0.154 s / 10,000,000
= 0.0154 us (0.0138 us with -O3)

CコードはPythonソリューションよりも約23倍高速ですが、これは正常のようです。うまくいけば、私のC乱数ジェネレーターが機能します。

PyPyを使用すると、66.7 ns(ではなくus)を取得できますがnum_digits1、これはわずか4.3倍遅くなります。

于 2013-03-11T02:54:32.943 に答える
1

あなたのボトルネックは印刷物のステートメントだと思います。代わりに、結果をリストに保存してみてください。

def nDigits(i):
    return len(str(i))
results = []
for i in xrange(1000000):
    results.append(nDigits(i))
print len(results)

xrange代わりに使用しrange、追加しました0。私のマシンでは0.45秒で実行されます。

リスト内包表記を使用すると、時間が0.37秒に短縮されます。

def nDigits(i):
    return len(str(i))
results = [nDigits(i) for i in xrange(1000000)]
print len(results)

関数呼び出しのオーバーヘッドを削除すると、時間が0.31秒に短縮されます。

results = [len(str(i)) for i in xrange(1000000)]
print len(results)
于 2013-03-11T02:55:09.043 に答える
1

そんな遅い??に変更for i in range(100000):するとfor i in xrange(100000):、少なくとも私のコンピューターでははるかに高速になります (1 秒または 2 または 3)。

遅さはあなたの使用法が原因であると思われますrange(100000)

xrangeオブジェクトのリストを生成する代わりに、一度に 1 つのオブジェクトを生成するだけなので、より効率的です。この場合、優先する必要がありrangeます。

編集: @cge が問題に言及した後、元のコードを ( を使用してrange(100000)) テストしましたが、1 秒か 2 秒以内に非常に速く終了したため、これが問題の原因ではない可能性があります (何か怪しいことが起こりましたが、私にはできませんでした)。ここに投稿したコードからはわかりません)、xrangeとにかく使用することをお勧めします。

于 2013-03-11T02:38:05.647 に答える