f-strings为什么与%表示法相比较慢?

huangapple go评论102阅读模式
英文:

Why f-strings are slow compared to % notation?

问题

f-strings比其他字符串格式化方式更快。最近,我进行了一些小的研究,结果让人吃惊 - 使用f-strings的小段代码比百分号符号表示法需要更多的时间。有人可以解释原因吗?

代码如下:

from timeit import repeat

setup = 'i = 1.34234324'

for code in ['"%f %f" % (i, i)', "f'{i} {i}'"] * 5:
    t = min(repeat(code, setup, number=10000)) / 10000
    print(f'{int(t*1e9):4} ns ', code)

打印结果是:

 321 ns  "%f %f" % (i, i)
 782 ns  f'{i} {i}'
 322 ns  "%f %f" % (i, i)
 786 ns  f'{i} {i}'
 321 ns  "%f %f" % (i, i)
 779 ns  f'{i} {i}'
 320 ns  "%f %f" % (i, i)
 782 ns  f'{i} {i}'
 320 ns  "%f %f" % (i, i)
 780 ns  f'{i} {i}'

我使用的是Python 3.10.7。

我期望f-strings的性能更好。

我也希望得到哪种浮点数替代字符串的方式最快的答案。

英文:

I have been thought that f-strings are faster than other ways of string formatting.

Recently I have done a small research. The result was a surprise -- small code with f-strings takes more time than percentage notation. Can someone explain the reason why?

The code is following:

from timeit import repeat

setup = 'i = 1.34234324'

for code in ["'%f %f' % (i, i)", "f'{i} {i}'"] * 5:
    t = min(repeat(code, setup, number=10000)) / 10000
    print(f'{int(t*1e9):4} ns ', code)

The print result is :

 321 ns  '%f %f' % (i, i)
 782 ns  f'{i} {i}'
 322 ns  '%f %f' % (i, i)
 786 ns  f'{i} {i}'
 321 ns  '%f %f' % (i, i)
 779 ns  f'{i} {i}'
 320 ns  '%f %f' % (i, i)
 782 ns  f'{i} {i}'
 320 ns  '%f %f' % (i, i)
 780 ns  f'{i} {i}'

I use Python 3.10.7

I expected that f-strings would have greater performance.

I also would like to get the answer which way of float substituting into a string is the fastes.

答案1

得分: 1

以下是代码的翻译部分:

# 第一个代码段
i = 1.645649846546786534646568684564688646546548686465416574786
a = f"{i}"
print(a)

# 输出
1.6456498465467866

# 第二个代码段
i = 1.645649846546786534646568684564688646546548686465416574786
b = "%f" % (i)
print(b)

# 输出
1.645650

# 用16位小数精度进行比较的修改后的代码
"%.16f %.16f" % (i, i)

# 使用 timeit 进行性能比较
import timeit

timeit.timeit('a=f"{i}"', setup='i = 1.645649846546786534646568684564688646546548686465416574786', number=100000)
0.04724510000005466

timeit.timeit('a="%.16f" % (i)', setup='i = 1.645649846546786534646568684564688646546548686465416574786', number=100000)
0.03985800000009476

# f-string 与 % 相当
英文:

Look at below two snippets of code.

it will be slower for floats since f-string

does not truncate the float

and guarantees some 16 digits of precision

in all other cases it will be much faster

i=1.645649846546786534646568684564688646546548686465416574786
a=f"{i}"
print(a)

1.6456498465467866
i=1.645649846546786534646568684564688646546548686465416574786
b="%f"%(i)
print(b)

1.645650

You may ammend the code to following for

proper comparison use %f with 16 decimal points precision

"'%.16f %.16f' % (i, i)"

import timeit

timeit.timeit('a=f"{i}"',setup='i= 1.645649846546786534646568684564688646546548686465416574786',number=100000)
0.04724510000005466


timeit.timeit('a="%.16f"%(i)',setup='i= 1.645649846546786534646568684564688646546548686465416574786',number=100000)
0.03985800000009476

### f-string is comparable % 

huangapple
  • 本文由 发表于 2023年2月10日 02:34:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75403005.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定