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函数的性能的更多相关文章

  1. Python内置类型性能分析

    Python内置类型性能分析 timeit模块 timeit模块可以用来测试一小段Python代码的执行速度. class timeit.Timer(stmt='pass', setup='pass' ...

  2. 常用排序算法的python实现和性能分析

    常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...

  3. 【Python】常用排序算法的python实现和性能分析

    作者:waterxi 原文链接 背景 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试题整 ...

  4. 面试中常用排序算法的python实现和性能分析

    这篇是关于排序的,把常见的排序算法和面试中经常提到的一些问题整理了一下.这里面大概有3个需要提到的问题: 虽然专业是数学,但是自己还是比较讨厌繁琐的公式,所以基本上文章所有的逻辑,我都尽可能的用大白话 ...

  5. Python入门笔记(18):Python函数(1):基础部分

    一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/archive/2011/08/29/2153871.html 一般程序设计语言包含两种基本的抽象:过 ...

  6. 测试c语言函数调用性能因素之测试三

    函数调用:即调用函数调用被调用函数,调用函数压栈,被调用函数执行,调用函数出栈,调用函数继续执行的一个看似简单的过程,系统底层却做了大量操作. 操作: 1,               调用函数帧指针 ...

  7. 用C语言模仿Python函数

    首先得说明一点,C 语言不是函数式编程语言,要想进行完全的函数式编程,还得先写个虚拟机,然后再写个解释器才行(相当于 CPython ). 下面我们提供一个例子,说明 C 语言函数可以"适度 ...

  8. Python 3.X 调用多线程C模块,并在C模块中回调python函数的示例

    由于最近在做一个C++面向Python的API封装项目,因此需要用到C扩展Python的相关知识.在此进行简要的总结. 此篇示例分为三部分.第一部分展示了如何用C在Windows中进行多线程编程:第二 ...

  9. python函数,模块及eclipse使用

    一.eclipse的使用 1.作用 (1)最好用的IDE (2)可调式debug (3)查看可执行过程 (4)可查看源代码 2.安装eclipse及配置 目录安装Pythonpython for ec ...

随机推荐

  1. AJAX(Asynchronous JavaScript And XML)

    AJAX(Asynchronous JavaScript And XML):异步的javascript和xml技术 作用:在不刷新整个页面的情况下,通过XMLHttpRequest向后台偷偷发起请求, ...

  2. 客户端和后台交互日期注意点 sqlite日期字段使用Date类型的情况下

    不要直接传递时间类型 一般把时间格式化字符串后传递 不要传递Date().getTime() 毫秒数  非要使用的话需要在后台处理 传递的毫秒数 - TimeZone.getDefault().get ...

  3. nutzboot 项目打包排除或指定配置文件(夹)

    springboot 是一样的 我这里就是从springboot哪里拿过来的 (nutzboot2.x已测试可以使用) 排除指定文件 在pom 文件 build 标签内添加 resources < ...

  4. FireWall2

    配置防火墙步骤: 1.给接口配置ip,开 service-manage 服务 2.把接口画在zone区域 3.配置策略 4.服务器一定要开启服务 1. interface GigabitEtherne ...

  5. IntelliJ IDEA项目断开版本管理解决方案

    今天使用idea时打开项目突然发现项目不受svn管理(项目目录依然受svn管理,只是idea脱管了),如遇到可用以下方法: 图片示例: 1. 2. 希望能帮到你

  6. 查询AD中被锁定的账号并进行解锁

    1:查询AD中被锁定的账号: Search-ADAccount -LockedOut | export-csv -path c:\aaavvv.csv 2:解除锁定 Search-ADAccount ...

  7. [2015普及组-D]推销员 思维que

    题:https://www.cometoj.com/problem/0221 #include<iostream> #include<cstring> #include< ...

  8. Django使用DjangoUeditor教程

    文章目录 1.将下在DjangoUeditor解压2.将解压的文件夹复制到项目的根目录中,这里使用的是虚拟环境3.进入到DjangoUedior3-master文件下,执行离线安装命令 python ...

  9. Mac环境下安装Redis

    转自:http://www.jianshu.com/p/6b5eca8d908b -安装 下载安装包 redis-3.0.7.tar.gz 官网地址:http://redis.io/download ...

  10. python模块之shelve,xml,hashlib,configpaser

    shelve shelve模块也是一种可以将数据序列化的模块 使用方法 1. open 2. 读写 3. close 特点:使用方法比较简单 提供一个文件名字就可以开始读写,读写的方法和字典一致;跨平 ...