省流助手:isinstance最快
最近夯实基础,无意间发现了关于类型判断几个常用的代码,决定将他们测试一下
结果如下:(这个代码太丑啦!别用这个!)
import datetime
bt = 1000000 # 循环次数
t = 1 # 大循环次数
st = 1000 # 小循环次数
c1_a = c2_a = c3_a = c4_a = datetime.datetime.now() - datetime.datetime.now() # 初始化时间总和
for i in range(t):
# 1.type(a) == type(0)
n = datetime.datetime.now() # 记录当前时间
for i in range(bt):
a = 0
if type(a) == type(0):
for i in range(st):
pass
c1 = datetime.datetime.now() - n # 记录所需时间
# 2.type(a) == int
n = datetime.datetime.now()
for i in range(bt):
a = 0
if type(a) == int:
for i in range(st):
pass
c2 = datetime.datetime.now() - n
# 3.type(a) is int
n = datetime.datetime.now()
for i in range(bt):
a = 0
if type(a) is int:
for i in range(st):
pass
c3 = datetime.datetime.now() - n
# 4.isinstance(a, int)
n = datetime.datetime.now()
for i in range(bt):
a = 0
if isinstance(a, int):
for i in range(st):
pass
c4 = datetime.datetime.now() - n
c1_a += c1 # 总循环时间
c2_a += c2
c3_a += c3
c4_a += c4
cc1 = (c1_a - c2_a) / t # 循环时间差值的平均值
cc2 = (c1_a - c3_a) / t
cc3 = (c1_a - c4_a) / t
print(cc1, cc2, cc3) # 0:00:06.850927 0:00:06.632723 0:00:07.695564
print(c1_a, c2_a, c3_a, c4_a) # 0:00:56.985577 0:00:50.134650 0:00:50.352854 0:00:49.290013
t = 10时
出现了意想不到的结果,我以为是BUG,所以把负数删了,后来发现不对劲。
发现第一种本应该最费时的情况竟然耗时最短,第四种本应最省时的竟然最耗时。
# t = 10
# 0:09:08.910747 0:09:14.997191 0:09:36.324098 0:09:41.848613
在编写代码时的想法本来是来凸显第四种方法的优越性,结果“弄巧成拙”,出现了这样的情况
为了排除偶然性就又运行了10次(相当于t=100)
结果如下:
# 0:00:01.415140 -1 day, 23:59:59.444459 -1 day, 23:59:58.753268
# 0:08:22.830703 0:08:08.679304 0:08:28.386113 0:08:35.298028
#
# 0:00:01.709234 -1 day, 23:59:57.812550 -1 day, 23:59:57.494091
# 0:16:20.585755 0:16:03.493415 0:16:42.460255 0:16:45.644845
#
# 0:00:01.372980 -1 day, 23:59:55.695308 -1 day, 23:59:55.852940
# 0:24:09.404787 0:23:55.674987 0:24:52.451710 0:24:50.875390
#
# 0:00:01.427868 -1 day, 23:59:53.755290 -1 day, 23:59:53.780046
# 0:32:02.669039 0:31:48.390363 0:33:05.116144 0:33:04.868579
#
# 0:00:02.173032 -1 day, 23:59:52.651831 -1 day, 23:59:52.697728
# 0:40:05.825056 0:39:44.094741 0:41:19.306743 0:41:18.847771
#
# 0:00:03.657786 -1 day, 23:59:51.982609 -1 day, 23:59:51.689834
# 0:48:15.161070 0:47:38.583206 0:49:35.334984 0:49:38.262729
#
# 0:00:03.731264 -1 day, 23:59:49.942986 -1 day, 23:59:50.288051
# 0:56:15.179770 0:55:37.867134 0:57:55.749915 0:57:52.299263
#
# 0:00:04.572990 -1 day, 23:59:48.902226 -1 day, 23:59:49.297376
# 1:04:20.859753 1:03:35.129857 1:06:11.837498 1:06:07.885988
#
# 0:00:04.740583 -1 day, 23:59:47.000354 -1 day, 23:59:47.467567
# 1:12:20.141157 1:11:32.735325 1:14:30.137616 1:14:25.465485
#
# 0:00:04.157962 -1 day, 23:59:45.509244 -1 day, 23:59:46.017190
# 1:20:25.830675 1:19:44.251058 1:22:50.738232 1:22:45.658778
上述原因可能是for循环写的不对
运行代码为下:
import time # 用time,这样时间的类型就是float
def xun(zx):
bt = 100000 * 10 # 从基础(共10s)上每x10,时间都x10
n = time.time() # 记录当前时间
for i in range(bt):
exec(zx, {'a': 0})
c = time.time() - n # 记录运行时间
return c
t = 5000 # 大循环次数
cc1 = cc2 = cc3 = cc4 = 0
for i in range(t):
c1 = xun('if type(a) == type(0):pass')
cc1 += c1
c2 = xun('if type(a) == int:pass')
cc2 += c2
c3 = xun('if type(a) is int:pass')
cc3 += c3
c4 = xun('if isinstance(a, int):pass')
cc4 += c4
print(i + 1)
url = 'time_log.txt'
with open(url, 'a') as f:
f.write(str(i + 1) + '\n')
f.write('%.4f, %.4f, %.4f, %.4f \n' % (c1, c2, c3, c4))
f.write('%.4f, %.4f, %.4f, %.4f \n' % (cc1, cc2, cc3, cc4))
运行结果出来了
if type(a) == type(0):pass | 平均运行时间14.366s | 总计运行时间71834.7907s |
if type(a) == int:pass | 平均运行时间12.585s | 总计运行时间62922.1056s |
if type(a) is int:pass | 平均运行时间12.579s | 总计运行时间62896.3178s |
if isinstance(a, int):pass | 平均运行时间12.347s | 总计运行时间61739.4633s |
5000行数据不大,但是不让上传,有兴趣的朋友可以私信我或者留下邮箱,我发给你
下面我发一个小的截取(已排序)
我以第四种方法标准,在2996行之前,第四种方法的执行时间都在12秒内(下同)
2995 | 13.9656 | 12.2321 | 12.2305 | 11.9997 |
2996 | 13.966 | 12.2324 | 12.2308 | 12 |
4171 | 15.1826 | 13.1731 | 13.3264 | 12.9896 |
4172 | 15.2013 | 13.1745 | 13.331 | 13.004 |
4907 | 17.2892 | 15.2333 | 15.2072 | 14.9996 |
4908 | 17.3041 | 15.2443 | 15.2087 | 15.0163 |
4994 | 20.7491 | 20.206 | 17.7662 | 19.3779 |
4995 | 21.0726 | 20.6068 | 18.1226 | 20.036 |
4996 | 22.3032 | 20.701 | 19.8279 | 20.5262 |
4997 | 23.9876 | 22.0374 | 19.9035 | 20.7665 |
4998 | 24.6108 | 22.7413 | 20.5408 | 22.2632 |
4999 | 25.6091 | 24.4432 | 22.8653 | 22.5206 |
在编写上述代码时,只想实现功能,再次回顾发现代码写的太难看了,所以美化一下。
import time # 用time,这样时间的类型就是float
t = 1 # 大循环次数
def xun(zx):
bt = 100000 * 1 # 从基础(共10s)上每x10,时间都x10
n = time.time() # 记录当前时间
for i in range(bt):
exec(zx, {'a': 0})
c = time.time() - n # 记录运行时间
return c
c1 = c2 = c3 = c4 = 0
for i in range(t):
c1 += xun('if type(a) == type(0):pass')
c2 += xun('if type(a) == int:pass')
c3 += xun('if type(a) is int:pass')
c4 += xun('if isinstance(a, int):pass')
print('%.4f, %.4f, %.4f, %.4f' % (c1, c2, c3, c4)) # 输出所需时间
正好在学习装饰器,所以加装了装饰器。
import time
t = 1 # 大循环次数
def info(func):
def wrapper(*args, **kwargs):
n = time.time() # 记录当前时间
func(*args, **kwargs)
m = time.time() - n # 记录运行时间
return m
return wrapper
@info
def xun(zx):
bt = 100000 * 10 # 从基础(共10s)上每x10,时间都x10
for i in range(bt):
exec(zx, {'a': 0})
c1 = c2 = c3 = c4 = 0
for i in range(t):
c1 += xun('if type(a) == type(0):pass')
c2 += xun('if type(a) == int:pass')
c3 += xun('if type(a) is int:pass')
c4 += xun('if isinstance(a, int):pass')
print('%.4f, %.4f, %.4f, %.4f' % (c1, c2, c3, c4)) # 输出所需时间
如有转载,请注明原文地址
否则我会将根据《中华人民共和国著作权法》对抄袭人提起诉讼