【问题标题】:Should I use float literals to represent integer numbers as floats in Python?我应该使用浮点文字将整数表示为 Python 中的浮点数吗?
【发布时间】:2018-10-02 15:26:31
【问题描述】:

考虑一个返回一半浮点参数的函数。是第一个好还是第二个更好?

def half_a(x: float) -> float:
    return x / 2

def half_b(x: float) -> float:
    return x / 2.0

是否有任何性能差异,或者是否有一种风格约定会说其中一个比另一个更好?

显然half_a 看起来更好,更复杂的代码段可能会变得更易读,但在其他一些语言中,使用half_b 版本以避免运行时类型转换是必要的或更可取的。

【问题讨论】:

  • 是的,第二种方式更好。但是第一种方式是可以容忍的。
  • 我秒秒
  • 我现在选择第一个。 Python 2 需要第二种方法来保证使用了浮点除法,但是在 Python 3 的 / 运算符和类型注释之间,我更喜欢整数分母来强调你正在除以 exactly i> 2,而不是在某个浮点容差范围内等于 2 的某个数字。
  • 整数 2 将完全转换为 2.0,但它必须在每次调用时由 float.__div__ 转换。当然,这是一个非常便宜的转换,老实说,我不确定它是否涉及创建 Python 浮点对象,或者它发生在 C 级别,避免创建新的 Python 对象。如果你真的想在这里对性能进行微优化,请避免缓慢的 Python 函数调用。并使用x * 0.5 而不是x / 2.0; 0.5 也精确地表示为浮点数,因为它是小二进制幂的小​​倍数。
  • @Ivan 乘法比除法稍微简单一些。一方面,它不必处理除以零。在古代,CPU的乘法肯定比除法快。我不知道这些天是否有明显的差异,如果有,是否与 CPython 有关,但旧习惯很难改掉。 :)

标签: python performance floating-point coding-style


【解决方案1】:

很难知道是否存在性能差异(如果存在,则绝对可以忽略不计)。关于风格,也没有共同的约定。但是,如果您使用的是 python 3+,我会选择第一个。 Python 3 有一个不同的整数除法运算符。见下文

x = 2
print(type(x)) # int
print(type(x / 2)) # float
print(type(x // 2)) # int

另一方面,如果您使用的是 python 2,您可能应该选择第二个,因为如果您的参数恰好是 int

print(2/5) # 0

【讨论】:

  • // 是地板除法,而不是整数除法。试试7.75 // 2.5
  • 谢谢。很高兴知道。实际上,我刚刚检查并发现 / 总是返回 float 即使在像 4 / 2 这样的情况下。
【解决方案2】:

float 除以floatfloat 除以int 稍快:

>>> timeit.timeit('n/2', 'n=123456.789') 
0.04134701284306175
>>> timeit.timeit('n/2.0', 'n=123456.789')
0.03455621766488548
>>> timeit.timeit('[n/2 for n in r]', 'r = [n*5/1.1 for n in range(1, 10001)]', number=10000)
5.177127423787169
>>> timeit.timeit('[n/2.0 for n in r]', 'r = [n*5/1.1 for n in range(1, 10001)]', number=10000)
4.067747102254316

【讨论】:

  • Python 3(由类型注释暗示)总是返回一个浮点数,即使两个操作数都是整数。
  • 此外,操作被包装在函数调用中,这比简单地执行除法要慢一个数量级。 float/float 单独可能是最快的,但在上下文中并不重要。
猜你喜欢
  • 1970-01-01
  • 2013-05-07
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
  • 2021-09-20
  • 1970-01-01
相关资源
最近更新 更多