Python 隐式和显式转换为浮点之间有区别吗?
我试图比较使用显式(即Python 隐式和显式转换为浮点之间有区别吗?,python,python-2.7,Python,Python 2.7,我试图比较使用显式(即float(n))和隐式(即n*1.0或n/1.0)将int转换为float的时间,时间几乎相同 除了可读性之外,是否有理由使用显式方式?有实际的区别吗 输出: 0.626700733696 0.634305166349 0.628865431089 编辑(因为大部分时间都浪费在列表上): 该测量不存在列表理解偏差 输出 0.0105130892657 0.00183750462634 # ~6 times faster than explicit 0.004511
float(n)
)和隐式(即n*1.0
或n/1.0
)将int转换为float的时间,时间几乎相同
除了可读性之外,是否有理由使用显式方式?有实际的区别吗
输出:
0.626700733696
0.634305166349
0.628865431089
编辑(因为大部分时间都浪费在列表上):
该测量不存在列表理解偏差
输出
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
您的测量结果是错误的,因为您正在将生成器理解传递给
timeit
,因此根本没有对内部进行评估(顺便说一句,克里斯指出了这一点)
为什么不避免循环(由于其他偏见:range
在python 2中扩展为list,创建列表理解或为与表达式同时测量的
循环控件),只需执行以下操作:
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
- 关键字参数测试(
,再次感谢Chris)float(x=1)
1.0
编辑:我关于其他代码“矮化”差异的理论让我感到痛苦:我忘记了使用n
也涉及名称查找,所以我改变了我的工作台,删除了所有名称查找(除了带有float
的那一个):
这给了我(在我可怜的i5机器上)
现在float
确实显示了它的缓慢性(我添加了一个简单的float-literal工作台,只是为了确保Python不会优化文本计算)
float
construct也更灵活,并且可以很有用:您可以重新定义它来做一些稍有不同的事情,即使它不被推荐,或者只是为了取笑您的朋友:
>>> float=lambda x : x+.000001
>>> float(1)
1.000001 (now is floating point math broken? :))
剩下的时间,乘以
1。
更快。你的测量是错误的,因为你将生成器理解传递给了timeit
,所以内部根本没有评估(顺便说一句,克里斯指出了这一点,这要归功于他)
为什么不避免循环(由于其他偏见:range
在python 2中扩展为list,创建列表理解或为与表达式同时测量的
循环控件),只需执行以下操作:
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
- 关键字参数测试(
,再次感谢Chris)float(x=1)
1.0
编辑:我关于其他代码“矮化”差异的理论让我感到痛苦:我忘记了使用n
也涉及名称查找,所以我改变了我的工作台,删除了所有名称查找(除了带有float
的那一个):
这给了我(在我可怜的i5机器上)
现在float
确实显示了它的缓慢性(我添加了一个简单的float-literal工作台,只是为了确保Python不会优化文本计算)
float
construct也更灵活,并且可以很有用:您可以重新定义它来做一些稍有不同的事情,即使它不被推荐,或者只是为了取笑您的朋友:
>>> float=lambda x : x+.000001
>>> float(1)
1.000001 (now is floating point math broken? :))
剩下的时间,乘以
1。
会更快。可读性不是一个实际的区别吗?当然,实现是不同的,例如尝试dis.dis('float(n)')
或dis.dis('n*1.0')
,但确实不要重新发明float()
毫无理由,您也在使用python 2,并且range
生成一个列表。这会使你的思维产生偏差measurements@Jean-弗朗索瓦·法布实际上时机不好,因为他们从来没有重复过这个过程generator@CIsForCookies1.
短于1.0
可读性不是一个实际的区别吗?当然,实现是不同的,例如尝试dis.dis('float(n)')
或dis.dis('n*1.0')
,但是真的不要无缘无故地重新发明float()
,而且您正在使用python 2,并且range
生成一个列表。这会使你的思维产生偏差measurements@Jean-弗朗索瓦·法布实际上时机不好,因为他们从来没有重复过这个过程generator@CIsForCookies1.
短于1.0
刚要回答我更新的测量值(无列表比较)。。。当检查100000次时,1*1.0
似乎是float(1)
Nice summary+1的1/10倍,另一个原因是float()
可能比较慢(在Py 3.7之前)是它必须检查关键字参数,你可以做float(x=1)
刚刚要回答我更新的测量值(没有列表比较)。。。当检查100000次时,1*1.0
似乎是float(1)
Nice summary+1的1/10倍,另一个原因float()
可能比较慢(在Py 3.7之前)是它必须检查关键字参数,您可以执行float(x=1)
>>> float=lambda x : x+.000001
>>> float(1)
1.000001 (now is floating point math broken? :))