字符串格式设置是否比将 Double 转换为 Int 更昂贵?

Is String formatting more expensive than casting a Double to an Int?

提问人:younes alaoui 提问时间:5/10/2023 最后编辑:younes alaoui 更新时间:5/11/2023 访问量:151

问:

在我用 Swift 编写的程序中,我必须在两者中选择一个,但我想我使用哪种编程语言并不重要。

我知道字符串格式非常昂贵,并且怀疑它比将 Double 转换为 Int 更昂贵,但我什至不确定,最重要的是,截至目前,我不明白为什么会这样。

另外,我在这里要做的是截断一个数字并将其打印到控制台,而不带小数部分(这意味着我不希望它看起来像这样,而是像这样)。最有效的方法是什么?0.00

有人可以启发我吗?

下面是代码(第一行的字符串格式和第二行的强制转换):

print(String(format: "%.0f", sender.value))

Int(sender.value)
Swift 转换 字符串格式

评论

0赞 younes alaoui 5/10/2023
您指的是整个代码还是只是格式和转换?因为这只是基本的东西,没什么花哨的,我猜......
1赞 Brian Goetz 5/10/2023
另请注意,两者做不同的事情。格式化双精度值会保留值的非整数部分;将 cast 转换为 int 会丢弃它。如果你真的需要那部分值,那么丢弃它是错误的,它是否无限快也没关系,因为你的程序仍然是错误的。
0赞 HangarRash 5/10/2023
@younesalaoui 仅相关代码。但是你现在发布的两条线彼此无关。为什么要比较打印字符串格式和琐碎的强制转换?难道不应该比较两个 print 语句还是其他两行可比较的代码吗?
1赞 Leo Dabus 5/11/2023
与您的问题无关,但如果您需要获取浮点的全部部分,请查看这篇文章。顺便说一句,你不是在向 Int 投射,你是在胁迫它。modf(sender.value).0

答:

5赞 Brian Goetz 5/10/2023 #1

这并不能回答近似的问题,但希望可以算作“启蒙”。

答案是:不要再担心微性能问题;大约 99.999% 的时间,它们是一种危险的分心。而是专注于编写清晰、可读的代码,这些代码显然是正确的。一个快速但错误的程序比根本没有程序要糟糕得多。另一方面,一个正确但可能更快的程序仍然非常好。当你如此出色,以至于你的程序一直都是正确的,那么也许是时候开始考虑提高性能了。如果需要,可以优化清晰正确的代码;“聪明的”快速但错误的代码很少能在不付出更多努力的情况下得到纠正。(举个例子:你的“更快”版本会丢弃可能很重要的信息:双精度的非整数部分。也许没关系,也许不是 -- 你没说过 -- 但这是人们经常犯的那种错误,当他们让性能领先于正确性时。

对于您的特定问题,动态甚至更糟,因为格式化字符串只有一个原因 - 那就是将其写出到某个 IO 通道。IO 已经比计算成本高得多,因此在 99.999% 的情况下,在通往 IO 的途中进行的小计算成本是 5 倍还是 10 倍并不重要。

此外,我们“知道”的关于性能的大部分知识(“我知道字符串格式非常昂贵”)只是传说,而且通常是错误的或过时的。对非专家所说的“昂贵”要非常非常怀疑。

所以答案是“别担心,做清晰、正确、可读的事情。

评论

1赞 Holger 6/29/2023
值得注意的是,所提出的问题没有多大意义,因为铸造和印刷是两种完全不同的操作,结果不同。只有当我们假设对结果的整数进行隐含打印时,它才具有可比性。然后,不仅 I/O 主导性能,整数的打印也包含相同的格式化操作,即创建十进制表示的“格式化”。程序员经常忽略的是,无论我们是否使用格式化 API(或隐含转换),十进制表示对计算机来说都不是自然的......
0赞 Sulthan 5/10/2023 #2

当我们谈论格式化的性能时,我们指的是本地化格式化。这意味着本地化小数分隔符、分组分隔符等。想象一下 .NumberFormatter

但是,昂贵的不是实际的格式设置,而是格式化程序的创建,因为这会迫使应用程序加载相当复杂的 Unicode 信息。当我说昂贵时,我的意思是相对而言。只有当你尝试每秒做数百次时,你才会看到一个问题。

您正在做的只是一个基本数字到字符串的转换。没什么太复杂的。根据您的用例,您可能会通过以不同的方式执行此操作来节省几毫秒,但除此之外,这是一个有效的解决方案。

试图提高其性能是没有意义的。