【问题标题】:Does print() / println() slow execution?print() / println() 执行速度会变慢吗?
【发布时间】:2015-02-26 09:42:05
【问题描述】:

我有一个包含几千行代码的应用程序,在该代码中有很多 println() 命令。这会减慢应用程序的速度吗?它显然是在模拟器中执行的,但是当您从应用商店/TestFlight 存档、提交和下载应用时会发生什么。这段代码是否仍然“活跃”,“注释掉”的代码呢?

当我提交到测试飞行/应用商店时,它是真的从未读过还是应该删除注释掉的代码?

【问题讨论】:

  • 即使对性能没有影响,您也应该删除不必要的打印调用。它们最终会出现在设备日志中,您不想在该日志中发送无用信息的垃圾邮件。

标签: ios swift


【解决方案1】:

是的,它确实减慢了代码速度。
printprintln 都会降低应用程序的性能。

Println 问题

println 在 Swift 进行代码优化时不会被移除。

for i in 0...1_000 {
  println(i)
}

此代码无法优化,并且在编译汇编代码后会执行一个包含 1000 条指令的循环,这些指令实际上并没有做任何有价值的事情。

分析汇编代码

问题在于 Swift 编译器无法使用 printprintln 命令对代码进行优化优化。 如果您查看生成的汇编代码,您可以看到它。

您可以使用Hopper Disassembler 查看汇编代码,也可以使用swiftc 编译器将 Swift 代码编译为汇编:

xcrun swiftc -emit-assembly myCode.swift

Swift 代码优化

让我们看几个例子以便更好地理解。
Swift 编译器可以消除很多不必要的代码,比如:

  • 空函数调用
  • 创建未使用的对象
  • 空循环

示例

class Object {
  func nothing() {
  }
}

for i in 0...1_000 {
  let object = Object3(x: i)
  object.nothing()
  object.nothing()
}

在这个例子中,Swift 编译器会做这个优化:

1.删除两个nothing方法调用

在此之后循环体将只有 1 条指令

for i in 0...1_000 {
  let object = Object(x: i)
}

2. 然后它会删除创建Object 实例,因为它实际上没有被使用。

for i in 0...1_000 {
}

3.最后一步是删除空循环。
我们最终没有代码可以执行

解决方案

  • 注释掉printprintln

这绝对不是最好的解决方案。
//println("A")

  • 使用DEBUG预处理器语句

使用此解决方案,您可以简单地更改 debug_print 函数的逻辑
debug_println("A)

func debug_println<T>(object: T) {
  #if DEBUG
    println(object)
  #endif
}

结论

始终从发布应用程序中删除 printprintln!!

如果添加 printprintln 指令,则 Swift 代码无法以最佳方式优化,并可能导致性能大幅下降。

【讨论】:

  • debug_println 只有在启用了整个模块优化的情况下才会被优化。并且它需要在同一个模块中(应用程序不能使用框架中的版本),否则它不能被完全优化掉。
【解决方案2】:

通常,您应该在生产应用程序中启用任何形式的日志记录,这很可能不会影响性能,但将其保持启用和不需要是不好的做法。

对于注释代码,这是无关紧要的,因为它会被编译器忽略并且不会成为最终二进制文件的一部分。

查看这个关于如何在生产代码中禁用println()的答案,有多种解决方案,Remove println() for release version iOS Swift

由于您不想为了发布而将所有 println() 调用注释掉,因此最好禁用它们,否则会浪费大量时间。

【讨论】:

  • 好的,我明白了,但只需搜索 println 并替换为 //println 也可以解决问题。但是,当然,如果您想保留其中的一部分,您帖子中的解决方案是更好更细微的选择。
  • 当然可以,但是我链接的答案中的方法将为您提供更大的灵活性,并允许它在您从调试版本更改为发布版本时自动发生。祝你好运:)
【解决方案3】:

printLn 应该不会产生太大影响,因为大部分操作在此之前已经执行。

注释掉的代码有时很有用,尽管它会使您的源代码难以阅读,但它绝对不会影响性能,而且我从来没有因注释掉的代码而拒绝任何东西,而且我的东西​​充满了它。

【讨论】:

  • 谢谢,这是非常有用的建议——这意味着我可以注释掉所有 println 命令,这样我就不必担心了。感谢您的回复!
猜你喜欢
  • 2019-07-27
  • 2012-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多