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
    可以是字符串)
  • 关键字参数测试(
    float(x=1)
    ,再次感谢Chris)
其他操作不涉及函数,而且速度非常快,当其中一个操作数正好是
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
    可以是字符串)
  • 关键字参数测试(
    float(x=1)
    ,再次感谢Chris)
其他操作不涉及函数,而且速度非常快,当其中一个操作数正好是
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@CIsForCookies
1.
短于
1.0
可读性不是一个实际的区别吗?当然,实现是不同的,例如尝试
dis.dis('float(n)')
dis.dis('n*1.0')
,但是真的不要无缘无故地重新发明
float()
,而且您正在使用python 2,并且
range
生成一个列表。这会使你的思维产生偏差measurements@Jean-弗朗索瓦·法布实际上时机不好,因为他们从来没有重复过这个过程generator@CIsForCookies
1.
短于
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? :))