Xcode 8 非常慢的 Swift 编译

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39879979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 09:24:03  来源:igfitidea点击:

Xcode 8 very slow Swift compiling

iosswiftxcodeswift3xcode8

提问by fancy

Ever since Swift 3 and Xcode 8 my project compiles quite slowly. Every time I add so much as an empty line to a file, recompiling takes a full minute. When I check the output, there is no particular file that takes very long. (I also used this tool to measure it: https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode)

从 Swift 3 和 Xcode 8 开始,我的项目编译速度非常慢。每次我向文件添加一个空行时,重新编译需要整整一分钟。当我检查输出时,没有需要很长时间的特定文件。(我也用这个工具来衡量它:https: //github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode

It always appears to compile 4 files at once. The "rythm" is quite steady. Just very slow...

它似乎总是一次编译 4 个文件。“节奏”相当稳定。就是很慢...

Also: Whenever I open or switch between files, it can take very long till I get autocomplete, or errors/warnings.

另外:每当我打开或在文件之间切换时,可能需要很长时间才能获得自动完成或错误/警告。

What things can I check? I almost feel like there is some flag I set that just drags down the build speed like crazy..

我可以检查哪些项目?我几乎觉得我设置了一些标志,只是像疯了一样拖累了构建速度..

EDIT:This is not a solution to the underlying problem, but I spent some time on moving more code to frameworks. This made a difference (simply because it has to recompile less files every time). This shouldn't be necessary but it got unbearable... I'm of course still looking very much for a proper solution.

编辑:这不是根本问题的解决方案,但我花了一些时间将更多代码移至框架。这产生了不同(仅仅是因为它每次必须重新编译更少的文件)。这不应该是必要的,但它变得无法忍受......我当然仍在寻找合适的解决方案。

回答by Constantin Saulenco

A issue with this problem is that we don't know where is the wrong initialization/declaration . A solution that my colleague suggest is to find which function take long time to compile so:

这个问题的一个问题是我们不知道错误的初始化/声明在哪里。我的同事建议的一个解决方案是找到哪个函数需要很长时间来编译:

  1. Go to Projectselect your target
  2. Build Settings-> Swift Compiler - Custom Flags
  3. Add to Other Swift Flags-Xfrontend -warn-long-function-bodies=50(50 represent the time in milliseconds)
  1. Project选择你的目标
  2. Build Settings-> Swift Compiler - Custom Flags
  3. 加到Other Swift Flags-Xfrontend -warn-long-function-bodies=50(50代表时间以毫秒为单位)

after that a warning should displayed as follow:

之后,警告应显示如下:

Getter 'frameDescription' took 108ms to type-check (limit: 50ms)

Getter 'frameDescription' 需要 108 毫秒进行类型检查(限制:50 毫秒)

and after that you know what to do ;)

之后你知道该怎么做;)

回答by Vlad

This is an issue with Xcode 8 where it does not perform incremental builds correctly. If you edit a single swift file it should compile only that file only. This has already been raised here: Xcode 8 does full project rebuild

这是 Xcode 8 的一个问题,它无法正确执行增量构建。如果您编辑单个 swift 文件,它应该只编译该文件。这已经在这里提出:Xcode 8 does full project rebuild

The 4 files at a time build sounds like Xcode is performing a full rebuild of the project which should not happen again if you only modified a single line in one file.

一次构建 4 个文件听起来像是 Xcode 正在执行项目的完全重建,如果您只修改了一个文件中的一行,则不应再次发生。

回答by Ben Simon

I've had the same issue only since upgrading to Swift 3/XCode 8 and it appears to be caused by large array literals, similar to this.

自从升级到 Swift 3/XCode 8 后,我才遇到同样的问题,它似乎是由类似于this 的大数组文字引起的。

I was able to fix the issue by adding type annotations to the variables being assigned to the array literal, e.g.

我能够通过向分配给数组文字的变量添加类型注释来解决这个问题,例如

let array: Array<String> = ["1", "2", "3", "4", "5", "6", "7", "8"]

instead of

代替

let array = ["1", "2", "3", "4", "5", "6", "7", "8"]

回答by bibscy

In my case I was using a helper function to save some data in Firebase. That function was returning a dictionary with about 20 elements and it would take about 40 mins to compile. My solution was to initialize an empty dictionary and then add the items one by one to someDict. Now it compiles in less than 30 seconds. I hope it helps.

就我而言,我使用辅助函数在 Firebase 中保存一些数据。该函数返回一个包含大约 20 个元素的字典,编译需要大约 40 分钟。我的解决方案是初始化一个空字典,然后将项目一项一项地添加到someDict. 现在它可以在不到 30 秒的时间内编译。我希望它有帮助。

Before

func toAnyObject() -> AnyObject {
  return
      ["BookingAmount":BookingAmount,
     "BookingNumber":BookingNumber,
     "PostCode":PostCode,
     "SelectedBathRow":SelectedBathRow,
     "SelectedBedRow":SelectedBedRow,
     "DateAndTime":DateAndTime,
     "TimeStampDateAndTime":TimeStampDateAndTime,
     "TimeStampBookingSavedInDB": TimeStampBookingSavedInDB,
     "FrequencyName":FrequencyName,
     "FrequecyAmount":FrequecyAmount,
     "insideCabinets": insideCabinets,
     "insideFridge": insideFridge,
     "insideOven": insideOven,
     "laundryWash": laundryWash,
     "interiorWindows": interiorWindows,
     "FullName":FullName,
     "SuppliesName":SuppliesName,
     "SuppliesAmount":SuppliesAmount,
     "FlatNumber":FlatNumber,
     "StreetAddress":StreetAddress,
     "PhoneNumber":PhoneNumber,
     "EmailAddress":EmailAddress] as AnyObject

}

After

  func toAnyObject() -> AnyObject {

    var someDict = [String : AnyObject]()
    someDict["BookingAmount"] = self.BookingAmount as AnyObject?
    someDict["BookingNumber"] = self.BookingNumber as AnyObject?
    someDict["PostCode"] = self.PostCode as AnyObject?
    someDict["SelectedBathRow"] = self.SelectedBathRow as AnyObject?
    someDict["SelectedBedRow"] = self.SelectedBedRow as AnyObject?
    someDict["DateAndTime"] = self.DateAndTime as AnyObject?
    someDict["TimeStampDateAndTime"] = self.TimeStampDateAndTime as AnyObject?
    someDict["TimeStampBookingSavedInDB"] = self.TimeStampBookingSavedInDB as AnyObject?
    someDict["FrequencyName"] = self.FrequencyName as AnyObject?
    someDict["FrequecyAmount"] = self.FrequecyAmount as AnyObject?
    someDict["insideCabinets"] = self.insideCabinets as AnyObject?
    someDict["insideFridge"] = self.insideFridge as AnyObject?
    someDict["insideOven"] = self.insideOven  as AnyObject?
    someDict["laundryWash"] = self.laundryWash as AnyObject?
    someDict["interiorWindows"] = self.interiorWindows as AnyObject?
    someDict["FullName"] = self.FullName as AnyObject?
    someDict["SuppliesName"] = self.SuppliesName as AnyObject?
    someDict["SuppliesAmount"] = self.SuppliesAmount as AnyObject?
    someDict["FlatNumber"] = self.FlatNumber as AnyObject?
    someDict["StreetAddress"] = self.StreetAddress as AnyObject?
    someDict["PhoneNumber"] = self.PhoneNumber as AnyObject?
    someDict["EmailAddress"] = self.EmailAddress as AnyObject?

    return someDict as AnyObject
}

回答by uplearnedu.com

This worked for me on one of my projects.

这对我的一个项目有用。

Go to Product -> Scheme -> Edit Scheme. Select Build in left side column and uncheck "Find implicit dependencies" But this flag should remain checked when you are building the project for first time..

转到产品 -> 方案 -> 编辑方案。选择在左侧栏中构建并取消选中“查找隐式依赖项”但是当您第一次构建项目时,此标志应保持选中状态。

Source

来源

It was a simple project and it increased one of my builds from 1 minute to 2 seconds.

这是一个简单的项目,它将我的一个构建从 1 分钟增加到 2 秒。

On a physical Device I got these results. For one of my larger projects (42 files) in only decreased it from 2:36 to 2:20. Then I added: SWIFT_WHOLE_MODULE_OPTIMIZATION = YES to Build Settings as a user defined setting. The time went down to - 2:00

在物理设备上我得到了这些结果。对于我的一个较大的项目(42 个文件),它仅从 2:36 减少到 2:20。然后我添加: SWIFT_WHOLE_MODULE_OPTIMIZATION = YES 将构建设置作为用户定义的设置。时间下降到 - 2:00

On the simulator the build was 49 seconds the first time then I used.

在模拟器上,我第一次使用的构建时间为 49 秒。

Go to Product -> Scheme -> Edit Scheme. Select Build in left side column and uncheck "Find implicit dependencies" But this flag should remain checked when you are building the project for first time..

转到产品 -> 方案 -> 编辑方案。选择在左侧栏中构建并取消选中“查找隐式依赖项”但是当您第一次构建项目时,此标志应保持选中状态。

and the build took 7 seconds.

构建耗时 7 秒。

I hope this helps.

我希望这有帮助。

回答by Logan Sease

I was able to greatly reduce my swift project compile times by avoiding the use the Nil-Coalescing Operator and string concatenation.

通过避免使用 Nil-Coalescing Operator 和字符串连接,我能够大大减少我的 swift 项目编译时间。

In otherwords where I had something like:

换句话说,我有类似的东西:

let x = "one" + object.nullableProperty ?? ""

I changed it to

我把它改成

let x = String(format: "one %@", object.nullableProperty ?? "")

My compile times have dropped drastically- from 20 minutes to 20 seconds.

我的编译时间急剧下降——从 20 分钟缩短到 20 秒。

回答by Dylan Gattey

Make sure you're not combining arrays like let combinedArrays = array1 + array2. There's a known bug as well for type inference here, where Swift wastes time trying to figure out what type the combinedArraysshould be. Instead, [array1, array2].joined()should work just as well, and compile far faster.

确保您没有组合像let combinedArrays = array1 + array2. 这里也有一个已知的类型推断错误,Swift 浪费时间试图找出combinedArrays应该是什么类型。相反,[array1, array2].joined()应该也能正常工作,并且编译速度要快得多。

回答by NRitH

One common practice that slows down compile time is using Array.appendand String.append(or their +operator equivalents). For Strings, it's better to use a formatted string, so instead of

减慢编译时间的一种常见做法是使用Array.appendand String.append(或它们的+运算符等价物)。对于Strings,最好使用格式化的字符串,而不是

let hello = "Hello, "
let world = "World!"
let combinedString = hello + world

you should use

你应该使用

let combinedString = "\(hello)\(world)"

I can't remember the exact speedup, but it was on the order of 10 times for those particular lines. Odds are, thought, that this won't have a noticeable speedup for any but the tinest projects. For example, our project has hundredsof Swift files, as well as many Objective-C ones, and our compile times are often 10 minutes or more, sometimes even when the only change was to a non-Swift file.

我不记得确切的加速比,但对于那些特定的线路,它大约是 10 倍。很可能,除了最微小的项目,这不会有任何明显的加速。例如,我们的项目有数百个Swift 文件,以及许多 Objective-C 文件,我们的编译时间通常是 10 分钟或更长时间,有时甚至当唯一的更改是非 Swift 文件时