使用timeit测试Python函数的性能
timeit是Python标准库内置的小工具,可以快速测试小段代码的性能。
认识timeit
timeit 函数:
timeit.timeit(stmt, setup,timer, number)
参数说明:
- stmt: statement的缩写,你要测试的代码或者语句,纯文本,默认值是 "pass"
- setup: 在运行
stmt前的配置语句,纯文本,默认值也是 "pass" - timer: 计时器,一般忽略这个参数
- number:
stmt执行的次数,默认是1000000,一百万
repeat 函数:
timeit.repeat(stmt, setup, timer, repeat, number)
是timeit的repeat版,可以指定重复timeit的次数,默认是3次,然后返回一个数组。
举一个简单的例子来说明用法:
import timeit
print(timeit.timeit('output = 10*5')) # 0.014560436829924583
print(timeit.repeat('output = 10*5')) # [0.01492984383367002, 0.01342877489514649, 0.013638464966788888]
嗯,看上去没毛病,实际上谁也不会去测没有意义的加减乘除,我们需要测试自己的代码。
测试多行代码
测试多行代码可以用分号来连接语句。
print(timeit.timeit(stmt='a=10;b=10;sum=a+b'))
也可以用三引号来写stmt。
import timeit
import_module = "import random"
testcode = '''
def test():
return random.randint(10, 100)
'''
print(timeit.repeat(stmt=testcode, setup=import_module))
但是其实都挺扯的,自己的代码会那么简单?我们是模块化编程。
测试模块中的函数
如果你要测试的函数都在一个模块里,可以这样写timeit。
import timeit
import random
import arrow
# 本地函数
def stupid1():
return random.randint(1, 10)
# 依赖其他函数
def stupid2():
return stupid1()
# 依赖其他包或者模块
def stupid3():
return arrow.now()
print(timeit.timeit('stupid1()', setup='from __main__ import stupid1'))
print(timeit.timeit('stupid2()', setup='from __main__ import stupid2'))
print(timeit.timeit('stupid3()', setup='from __main__ import stupid3', number=100))
写成上面这样的其实还是单行的模式。
借用default_timer
timeit自带的default_timer可以借来用一下。
import timeit
import random
def test():
return random.randint(10, 100)
starttime = timeit.default_timer()
print("The start time is :",starttime)
test()
print("The time difference is :", timeit.default_timer() - starttime)
命令行的用法
timeit还支持命令行的调用方式,不过我觉得太累了,没必要去尝试。
C:\pythontest>python -m timeit -s 'text="hello world"'
20000000 loops, best of 5: 13.1 nsec per loop
分享一个案例
2月29那天,我想今年是闰年啊,计算闰年有几种算法啊?孔乙己说有3种:
def is_leap_year_0(year):
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
return True
else:
return False
else:
return True
else:
return False
def is_leap_year_1(year):
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def is_leap_year_2(year):
if year % 400 == 0:
return True
if year % 100 == 0:
return False
if year % 4 == 0:
return True
return False
这三种方法那种最好啊?这个不能一概而论吧,因为要看你的参数是什么,比如1991年不是闰年,方法0和方法1直接就返回了,但方法2还需要走到最后一个if才知道不是闰年。再比如2020年,方法2直接就返回了,但是方法0和1需要走到最里层的if才得到结果。所以我们需要取样测试才公平,比如从1900年到2900年,每个函数都跑10000遍。
timeit就不太方便了,它接受的参数哪能那么复杂,我们需要包装一下。
def perf_test(method):
years = range(1900, 2900)
if method == 0:
for y in years:
is_leap_year_0(y)
if method == 1:
for y in years:
is_leap_year_1(y)
if method == 2:
for y in years:
is_leap_year_2(y)
print(timeit('perf_test(0)', setup='from __main__ import perf_test', number=10000))
print(timeit('perf_test(1)', setup='from __main__ import perf_test', number=10000))
print(timeit('perf_test(2)', setup='from __main__ import perf_test', number=10000))
你们猜猜看哪个方法结果最好?你一定想不到。
1.6432780250906944
1.7527272370643914
0.0023122059646993876
其他的思路
timeit其实还是太弱了,随便测测还凑合,如果真要检查性能问题还是需要用更专业的手段。比如:
有机会我们下次再说。
关于作者:
Toby Qin, Python 技术爱好者,目前从事测试开发相关工作,转载请注明原文出处。
欢迎关注我的博客 https://betacat.online,你可以到我的公众号中去当吃瓜群众。
使用timeit测试Python函数的性能的更多相关文章
- Python内置类型性能分析
Python内置类型性能分析 timeit模块 timeit模块可以用来测试一小段Python代码的执行速度. class timeit.Timer(stmt='pass', setup='pass' ...
- 常用排序算法的python实现和性能分析
常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...
- 【Python】常用排序算法的python实现和性能分析
作者:waterxi 原文链接 背景 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试题整 ...
- 面试中常用排序算法的python实现和性能分析
这篇是关于排序的,把常见的排序算法和面试中经常提到的一些问题整理了一下.这里面大概有3个需要提到的问题: 虽然专业是数学,但是自己还是比较讨厌繁琐的公式,所以基本上文章所有的逻辑,我都尽可能的用大白话 ...
- Python入门笔记(18):Python函数(1):基础部分
一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/archive/2011/08/29/2153871.html 一般程序设计语言包含两种基本的抽象:过 ...
- 测试c语言函数调用性能因素之测试三
函数调用:即调用函数调用被调用函数,调用函数压栈,被调用函数执行,调用函数出栈,调用函数继续执行的一个看似简单的过程,系统底层却做了大量操作. 操作: 1, 调用函数帧指针 ...
- 用C语言模仿Python函数
首先得说明一点,C 语言不是函数式编程语言,要想进行完全的函数式编程,还得先写个虚拟机,然后再写个解释器才行(相当于 CPython ). 下面我们提供一个例子,说明 C 语言函数可以"适度 ...
- Python 3.X 调用多线程C模块,并在C模块中回调python函数的示例
由于最近在做一个C++面向Python的API封装项目,因此需要用到C扩展Python的相关知识.在此进行简要的总结. 此篇示例分为三部分.第一部分展示了如何用C在Windows中进行多线程编程:第二 ...
- python函数,模块及eclipse使用
一.eclipse的使用 1.作用 (1)最好用的IDE (2)可调式debug (3)查看可执行过程 (4)可查看源代码 2.安装eclipse及配置 目录安装Pythonpython for ec ...
随机推荐
- 二、linux-mysql -cmake方式安装mysql 5.5
1.安装解压cmake包 cmake软件cd /home/oldboy/tools/tar xf cmake-2.8.8.tar.gzcd cmake-2.8.8./configure#CMake ...
- rework-发出你的心声
生意人虚张声势的时候会给人什么感觉?都是些僵硬的措辞.官方的腔调.虚伪的友善.法律术语等.你一定看过这些玩意儿,就好像是机器人写出来的东西,这些公司在向你发话,而不是和你对话. 这种专业主义面具让人觉 ...
- OA项目-xadmin使用
############### xadmin安装和配置 ############### """ 环境: Python3.6.3 django1.11.11 创建dj ...
- Mysql 和 Java对比异同
1.求两个时间的差(天数) mysql : to_days 距离公元0年的天数 select TO_DAYS('2017-10-18 00:00:00'),TO_DAYS(NOW()), (TO_DA ...
- [LC] 107. Binary Tree Level Order Traversal II
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left ...
- C++ 中类的内存布局
在许多笔试面试中都会涉及到sizeof 运算符的求值问题. 这类问题主要分四类: 基本数据类型,如int,bool,fload,long,long,int * 等,这一类比较简单,但要注意x86和x6 ...
- Gas Station(Medium)
1.在做pat的to fill or not to fill的时候想起同样是加油站的题目,于是翻出来复习一下 2.关键在于理解潜在的条件.假设油量为tank,如果到了当前站i,tank<0,即不 ...
- .vimrc文件
1 set number 2 set shiftwidth=4 3 set softtabstop=4 4 set tabstop=4 5 set expandtab 6 "set hlse ...
- Linux考试试题
mkdir -p /data/oldboy touch lodboy.txt echo "inet addr:10.0.0.8 Bcast:10.0.0.255 Mask:255.255. ...
- C++逆序输出字符串
使用库函数 //使用库函数 #include <iostream> #include <string> #include <algorithm> using nam ...
