我尝试编写一个计算数字位数的函数,顺便说一句,我尝试比较不同方式的效率。 1. lenstr(i)方式:
def nDigits(i):
return len(str(i))
for i in range(100000):
print nDigits(i)
需要大约143.75s
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.35s
3.分工方式:
def nDigits(i):
t = 0
while i > 0:
t += 1
i /= 10
return t
for i in range(100000):
print nDigits(i)
需要大约143.43s
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.07s
C是否比python好2000倍......或者python有更好的方法来计算数字位数。大家好,请帮我。
答案 0 :(得分:1)
for i in range(100000):
更改为for i in xrange(100000):
,则会更快,至少在我的计算机上(1秒或2或3)。
我怀疑使用range(100000)
xrange
效率更高,因为它不是生成对象列表,而是一次只生成一个对象。在这种情况下,您应该优先于range
。
range(100000)
),它也在一两秒内完成得很快,所以这可能不是你问题的原因(发生了一些可疑的事情,我从你在这里发布的代码中看不到,但我建议你使用xrange
。
答案 1 :(得分:1)
简化您的测试用例并删除所有print
s:
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倍。
答案 2 :(得分: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)