浮动和隐式转换之间有区别吗?

时间:2018-02-26 14:35:09

标签: python python-2.7

我尝试比较使用显式(即float(n))和隐式(即n*1.0n/1.0)将int转换为浮点数的时间,并且时间几乎相同。

是否有理由使用除可读性之外的显式方式?有实际的区别吗?

import timeit
N = 100000

print timeit.timeit('(float(n) for n in range(1000))', number=N)
print timeit.timeit('(n*1.0 for n in range(1000))', number=N)
print timeit.timeit('(n/1.0 for n in range(1000))', number=N)

输出:

0.626700733696
0.634305166349
0.628865431089

编辑(因为大部分时间都浪费在列表理解上):

此测量没有列表理解偏差

import timeit
N = 100000

print timeit.timeit('float(1)', number=N)
print timeit.timeit('1*1.0', number=N)
print timeit.timeit('1/1.0', number=N)

输出

0.0105130892657
0.00183750462634   # ~6 times faster than explicit
0.00451134133505   # ~2 times faster than explicit

最后的同情

import timeit
N = 100000

print '='*40

print 'no variable look-up:'
explicit =  timeit.timeit('float(1)', number=N)
implicit_multiplication =  timeit.timeit('1*1.0', number=N)
implicit_division = timeit.timeit('1/1.0', number=N)
print 'explicit                                  ', explicit
print 'implicit multiplication                   ', implicit_multiplication
print 'implicit division                         ', implicit_division
print 'explicit to implicit multiplication ratio ', explicit / implicit_multiplication

print '='*40

print 'with variable look-up:'
explicit_with_look_up =   timeit.timeit('float(n)', number=N, setup = 'n=1')
implicit_multiplication_with_look_up =  timeit.timeit('n*1.0', number=N, setup = 'n=1')
implicit_division_with_look_up = timeit.timeit('n/1.0', number=N, setup = 'n=1')
print 'explicit                                  ', explicit_with_look_up
print 'implicit multiplication                   ', implicit_multiplication_with_look_up
print 'implicit division                         ', implicit_division_with_look_up
print 'explicit to implicit multiplication ratio ', explicit_with_look_up / implicit_multiplication_with_look_up


========================================
no variable look-up:
explicit                                   0.0117008736543
implicit multiplication                    0.00140456514782
implicit division                          0.0042846079441
explicit to implicit multiplication ratio  8.33060230236
========================================
with variable look-up:
explicit                                   0.0114346407568
implicit multiplication                    0.00372041813489
implicit division                          0.00400375711843
explicit to implicit multiplication ratio  3.07348269527

1 个答案:

答案 0 :(得分:3)

你的测量结果是错误的,因为你正在将生成器理解传递给timeit,因此根本没有对内部进行评估(Chris指出BTW的信用)

为什么不避免循环(因为其他偏差:range在python 2中扩展为列表,同时创建 list 理解或for循环控制作为你的表达)只做:

import timeit
N = 1000000

print (timeit.timeit('float(n)', number=N,setup = "n=100"))
print (timeit.timeit('n*1.0', number=N,setup = "n=100"))
print (timeit.timeit('n/1.0', number=N,setup = "n=100"))

使用非常简单的基准测量来衡量我想测量的内容,我会得到不同的结果:

0.2391901001877792
0.1120344300726624
0.11477763911405542

所以是的,调用float要慢得多,因为:

  • 函数调用
  • 名称查找(float可以重新定义,它不是关键字)
  • 参数测试(n可以是字符串)
  • 关键字参数测试(float(x=1),再次感谢Chris)

其他操作不涉及函数且非常快,并且可能优化为当其中一个操作数正好为1.0

时不执行任何操作 编辑:我关于其他代码的理论“让我看起来相形见绌”只是让我感到困惑:我忘了使用n也涉及名称查找,所以我改变了我的工作台以删除所有名称查找(除了{{{ 1}}):

float

给了我(在我可怜的i5机器上)

print (timeit.timeit('float(2.0)', number=N))
print (timeit.timeit('2*1.0', number=N))
print (timeit.timeit('2/1.0', number=N))
print (timeit.timeit('2.0', number=N))

现在1.5391184875027701 0.196832246702201 0.19605593720477255 0.11489053989433051 真的显示它的缓慢(我添加了一个简单的浮点文字工作台,只是为了确保Python不优化文字计算)

float构造也更灵活,并且可以是有用的:你可以重新定义它做一些稍微不同的东西,即使不推荐它或只是取笑你的朋友:

float

其余时间乘以>>> float=lambda x : x+.000001 >>> float(1) 1.000001 (now is floating point math broken? :)) 会更快。