Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.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循环比Excel VBA慢?_Python_Vba_Excel - Fatal编程技术网

Python循环比Excel VBA慢?

Python循环比Excel VBA慢?,python,vba,excel,Python,Vba,Excel,我在excel(VBA)和python之间运行了一个小测试,执行了一个简单的循环。代码如下所列。令我惊讶的是,vba比python快得多。几乎快了6倍。我认为,由于python通过命令行运行,性能会更好。你们对此有何评论 蟒蛇 import time import ctypes # An included library with Python install. start_time = time.time() for x in range(0, 1000000): print x

我在excel(VBA)和python之间运行了一个小测试,执行了一个简单的循环。代码如下所列。令我惊讶的是,vba比python快得多。几乎快了6倍。我认为,由于python通过命令行运行,性能会更好。你们对此有何评论

蟒蛇

import time
import ctypes  # An included library with Python install.
start_time = time.time()

for x in range(0, 1000000):
    print x

x = ("--- %s seconds ---" % (time.time() - start_time))
ctypes.windll.user32.MessageBoxA(0, x, "Your title", 1)
Excel(VBA)


慢的部分是
打印
。打印到控制台的速度非常慢,所以应该完全避免。我认为在Excel中设置单元格值要快得多


如果要比较计算速度,循环中不应该有任何I/O。相反,只计算处理整个循环所需的时间,而不在内部执行任何操作(或执行简单的操作,如添加数字或其他操作)。如果您这样做,您将看到Python非常快。

您的两个代码示例所做的事情并不相同。在Python代码中,内部循环必须:

  • 询问
    范围(0,1000000)
    中的下一个数字
  • 显示它
在VBA代码中,Excel必须:

  • 询问
    范围(“A1:A1000000”)
    中的下一个单元格(与Python范围无关)
  • 设置
    cell.Value
    属性
  • 运行Excel在更改单元格时执行的各种代码
  • 检查是否需要重新计算公式
  • 显示它
  • 增量
    x
让我们重写它,以便Python和VBA循环尽可能地执行相同的操作:

python
导入时间
导入ctypes
开始时间=time.time()
x=0

虽然x它随您需要执行的计算而变化,但很难通过简单的比较给出更快的证明。因此,我将以一种普通的方式分享我的经验,没有证据,但对可能产生巨大差异的事情发表一些评论

根据我的经验,如果将纯python和纯VBA之间代码完全相同的简单for循环进行比较,VBA大约快3倍。但是没有人用不同的语言做同样的事情。您必须应用每种语言的最佳实践

如果您应用VBA最佳实践,您可以通过声明变量和python中不可用的其他类似优化来加快速度。根据我的经验,这可以使代码速度提高2-3倍左右。因此,可以使VBA代码比python中的简单for循环快6-9倍左右

另一方面,如果应用python最佳实践,通常不会编写常规for循环。您将使用列表理解或使用numpy和scipy,它们在编译的C库中运行。这些解决方案比VBA代码快得多

一般来说,如果使用numpy和scipy执行复杂的矩阵计算,python将比VBA更快。在其他情况下,VBA速度更快

在python中,您还可以使用Numba,这给代码增加了一点复杂性,但它有助于生成编译代码并处理在GPU中运行的代码。它将使您的代码更快


这是我在纯计算方面的经验,主要涉及内部数组。我还没有将I/O与GUI、外部文件和数据库、网络通信或API的性能进行比较。

我调整了代码,使其在没有print语句的情况下运行,而您的表现恰到好处。谢谢,我对python的信心恢复了。听到这个消息我很高兴;)谢谢你的资源。很有见地。我想如果我们想提高性能,我们可以使用类似Cpython的东西,以便将代码进一步分解为编译语言。如果我们能通过这种方法击败VBA的性能,我会很感兴趣。@Jimmyn你是说Cython吗?您可能已经在使用CPython,这是该语言的参考实现。这些时间太小了:在基于操作系统的平台上,96 vs 33 ms的运行时间仍然太小,因为它与上下文切换、页面交换、JIT编译、延迟评估等数量级相同。。我会将主循环包装在一个外循环中,并运行至少10-15秒。最后,两者应该执行相同的ADD/JMP+分支错误预测,因此我希望它们是相同的。不像他们的编译器/解释器有很多不同之处。
Sub looptest()

Dim MyTimer As Double

MyTimer = Timer

Dim rng As Range, cell As Range
Set rng = Range("A1:A1000000")

x = 1
For Each cell In rng

    cell.Value = x
    x = x + 1
Next cell


MsgBox Timer - MyTimer
End Sub
import time
import ctypes
start_time = time.time()

x = 0
while x <= 1000000:
    x = x + 1

x = ("--- %s seconds ---" % (time.time() - start_time))
ctypes.windll.user32.MessageBoxA(0, x, "Your title", 1)
Declare Function QueryPerformanceCounter Lib "kernel32" (t As Currency) As Boolean
Declare Function QueryPerformanceFrequency Lib "kernel32" (t As Currency) As Boolean

Sub looptest()
    Dim StartTime As Currency
    QueryPerformanceCounter StartTime

    x = 0
    Do While x <= 1000000
        x = x + 1
    Loop

    Dim EndTime As Currency
    QueryPerformanceCounter EndTime
    Dim Frequency As Currency
    QueryPerformanceFrequency Frequency

    MsgBox Format$((EndTime - StartTime) / Frequency, "0.000")
End Sub