在 Python 中对运行时间进行基准测试

Posted

技术标签:

【中文标题】在 Python 中对运行时间进行基准测试【英文标题】:Benchmarking run times in Python 【发布时间】:2013-10-05 01:40:11 【问题描述】:

我必须对 JSON 序列化时间进行基准测试,并将其与 thrift 和 Google 的协议缓冲区的序列化时间进行比较。它也必须在 Python 中。

我正计划使用 Python 分析器。 http://docs.python.org/2/library/profile.html

探查器是查找函数运行时的最佳方式吗?还是在函数调用之前和之后输出时间戳是更好的选择?

或者有更好的方法吗?

【问题讨论】:

【参考方案1】:

来自您链接到的 profile 文档:

注意分析器模块旨在为给定程序提供执行配置文件,而不是用于基准测试目的(为此,有timeit 以获得相当准确的结果)。这尤其适用于针对 C 代码对 Python 代码进行基准测试:分析器会为 Python 代码引入开销,但不会为 C 级函数引入开销,因此 C 代码似乎比任何 Python 代码都快。

所以,不,您不想使用profile 对您的代码进行基准测试。您想使用profile 的目的是找出为什么您的代码太慢,在您已经知道它之后。

而且您也不希望在函数调用之前和之后输出时间戳。如果你不小心,有太多的事情可能会出错(使用错误的时间戳功能,让 GC 在测试运行过程中运行循环收集,包括循环计时中的测试开销等.),timeit 会为您处理所有这些。

这样的事情是对事物进行基准测试的常用方法:

for impl in 'mycode', 'googlecode', 'thriftcode':
    t = timeit.timeit('serialize(data)', 
                      setup='''from  import serialize; 
                               with open('data.txt') as f: data=f.read()
                            '''.format(impl),
                      number=10000)
    print(': '.format(impl, t)

(我在这里假设您可以编写三个模块,将三个不同的序列化工具包装在同一个 API 中,一个 serialize 函数接受一个字符串并用它做某事或其他事情。显然有不同的方法整理东西。)

【讨论】:

嘿,谢谢!这正是我一直在寻找的。 timeit 模块非常完美。我打算用探查器运行一堆数据一次。 timeit 函数让我可以运行一些时间很长的数据,这非常适合这些序列化包,因为它们只允许一次序列化高达 1M 的小块数据。现在唯一的问题是如何准确地比较它们。 Google 协议缓冲区使用一个方法调用进行序列化,而 thrift 使用三个消息调用进行序列化,前两个设置内存空间。所以我不确定如何准确比较。 @Nickthemagicman:如果您必须为每个节俭序列化使用三个方法调用,那么为所有三个方法调用编写一个包装器,这应该是一个公平的比较。如果您只需要使用前两个调用来序列化一大堆东西,请将前两个调用作为设置的一部分,并且只为第三个调用计时。【参考方案2】:

在基于问题开始和结束时的时间戳分析 Python 代码时应该小心。这没有考虑其他可能同时运行的进程。

相反,您应该考虑查看

Is there any simple way to benchmark python script?

【讨论】:

以上是关于在 Python 中对运行时间进行基准测试的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spark 控制台中对性能进行基准测试?

如何在处理程序中对龙卷风处理程序进行基准测试?

在 C# 中对小代码示例进行基准测试,这个实现可以改进吗?

在 JMH 中对具有不同值的循环进行微基准测试

在Go中对gRPC+ProtoBuf与Http+Json进行基准测试

Python 系统的基准测试系统性能