Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么int(len(str(k))比循环(while)快_Python_C_Performance - Fatal编程技术网

Python 为什么int(len(str(k))比循环(while)快

Python 为什么int(len(str(k))比循环(while)快,python,c,performance,Python,C,Performance,我想知道为什么这个功能: def digitk: 回程透镜 比这个快吗 def digitk: i=0 而k!=0: k=k//10 i+=1 返回i 为什么C中的情况正好相反?让我们看看如果我们将Python代码尽可能地翻译成C,会发生什么。我们可以通过以下方法轻松做到这一点: 您从中获得的机器代码并不是最佳的,但它足够接近快速测试。这使我们可以直接使用以下方法比较性能: # save this in a file named 'test.py' and run it using the #

我想知道为什么这个功能:

def digitk: 回程透镜 比这个快吗

def digitk: i=0 而k!=0: k=k//10 i+=1 返回i
为什么C中的情况正好相反?

让我们看看如果我们将Python代码尽可能地翻译成C,会发生什么。我们可以通过以下方法轻松做到这一点:

您从中获得的机器代码并不是最佳的,但它足够接近快速测试。这使我们可以直接使用以下方法比较性能:

# save this in a file named 'test.py' and run it using the
# same CPython you compiled testmod.pyx against

import timeit
from testmod import c_digit_loop, c_digit_str

def py_digit_loop(k):
    i = 0
    while k != 0:
        k = k // 10
        i += 1
    return i

def py_digit_str(k):
    return len(str(k))

def test1(name):
    print(name, timeit.timeit(name+"(1234567)", "from __main__ import "+name,
                              number=10000))

test1("py_digit_loop")
test1("py_digit_str")
test1("c_digit_str")
test1("c_digit_loop")
当我运行这个程序时,这是我在计算机上输入的输出。我已经手动排列了这些数字,以便用肉眼比较

py_digit_loop 0.004024484000183293
py_digit_str  0.0020454510013223626
c_digit_str   0.0009924650003085844
c_digit_loop  0.00025072999960684683
因此,这证实了您最初的断言:循环比在Python中转换为字符串要慢,但在C中则相反。但请注意,在C中转换为字符串仍然比在Python中转换为字符串快

为了确切地知道为什么会发生这种情况,我们需要比我今天上午想做的更深入地挖掘Python解释器的本质,但是我已经对它的本质有了足够的了解,可以大致地告诉您。CPython解释器不是很有效。即使是对小整数的操作也涉及到引用计数和堆上临时对象的构造。在Python中执行基本算法的循环每次迭代需要一个或两个scratch对象,具体取决于0、1、2、。。。他们被拘留了。通过转换为字符串并计算其长度来进行计算只需要为整个计算创建一个临时对象,即字符串。对于这两种Python实现,与这些scratch对象相关的簿记使实际计算的成本相形见绌

基于C字符串的实现执行的步骤几乎与基于Python字符串的实现完全相同,但是它的scratch对象是堆栈上的一个char数组,而不是一个成熟的Python字符串对象,而且这一切本身显然有利于40-50%的加速


基于C循环的实现为实际循环编译多达八条机器指令。没有内存访问。甚至连硬件分割指令都没有,这就是它的神奇之处。然后是数百条关于Python对象模型的指令。这0.00025秒中的大部分仍然是开销。

让我们看看如果我们将Python代码尽可能地翻译成C,会发生什么。我们可以通过以下方法轻松做到这一点:

您从中获得的机器代码并不是最佳的,但它足够接近快速测试。这使我们可以直接使用以下方法比较性能:

# save this in a file named 'test.py' and run it using the
# same CPython you compiled testmod.pyx against

import timeit
from testmod import c_digit_loop, c_digit_str

def py_digit_loop(k):
    i = 0
    while k != 0:
        k = k // 10
        i += 1
    return i

def py_digit_str(k):
    return len(str(k))

def test1(name):
    print(name, timeit.timeit(name+"(1234567)", "from __main__ import "+name,
                              number=10000))

test1("py_digit_loop")
test1("py_digit_str")
test1("c_digit_str")
test1("c_digit_loop")
当我运行这个程序时,这是我在计算机上输入的输出。我已经手动排列了这些数字,以便用肉眼比较

py_digit_loop 0.004024484000183293
py_digit_str  0.0020454510013223626
c_digit_str   0.0009924650003085844
c_digit_loop  0.00025072999960684683
因此,这证实了您最初的断言:循环比在Python中转换为字符串要慢,但在C中则相反。但请注意,在C中转换为字符串仍然比在Python中转换为字符串快

为了确切地知道为什么会发生这种情况,我们需要比我今天上午想做的更深入地挖掘Python解释器的本质,但是我已经对它的本质有了足够的了解,可以大致地告诉您。CPython解释器不是很有效。即使是对小整数的操作也涉及到引用计数和堆上临时对象的构造。在Python中执行基本算法的循环每次迭代需要一个或两个scratch对象,具体取决于0、1、2、。。。他们被拘留了。通过转换为字符串并计算其长度来进行计算只需要为整个计算创建一个临时对象,即字符串。对于这两种Python实现,与这些scratch对象相关的簿记使实际计算的成本相形见绌

基于C字符串的实现执行的步骤几乎与基于Python字符串的实现完全相同,但是它的scratch对象是堆栈上的一个char数组,而不是一个成熟的Python字符串对象,而且这一切本身显然有利于40-50%的加速


基于C循环的实现为实际循环编译多达八条机器指令。没有内存访问。甚至连硬件分割指令都没有,这就是它的神奇之处。然后是数百条关于Python对象模型的指令。这0.00025秒中的大部分仍然是开销。

FWIW,len已经返回int,无需再次转换。为什么更快:因为str和len是用C实现的,并且经过高度优化,而userland代码中的循环需要更多的步骤才能完成。@deceze声称,C中的循环更快。我对此不确定,但是,正如前面所说的,在Python中循环更慢-这可能是因为你所说的…@Kai
C编译器可以高度优化这样的循环。我对C的了解还不足以支持或反驳它实际上会更快的说法。但是Python肯定不会进行那种级别的优化,实际上会在循环中执行所有这些步骤,这显然要慢一些?…?!FWIW,len已返回int,无需再次转换。为什么更快:因为str和len是用C实现的,并且经过高度优化,而userland代码中的循环需要更多的步骤才能完成。@deceze声称,C中的循环更快。我不确定这一点,但是,如前所述,在Python中,循环速度较慢-这可能是因为您所说的…@Kai C编译器可以高度优化这种循环。我对C的了解还不足以支持或反驳它实际上会更快的说法。但是Python肯定不会进行那种级别的优化,实际上会在循环中执行所有这些步骤,这显然要慢一些?…?!