简体   繁体   English

Xcode 8非常慢的Swift编译

[英]Xcode 8 very slow Swift compiling

Ever since Swift 3 and Xcode 8 my project compiles quite slowly. 自从Swift 3和Xcode 8以来,我的项目编译速度非常慢。 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 ) (我也用这个工具测量它: https//github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode

It always appears to compile 4 files at once. 它似乎总是一次编译4个文件。 The "rythm" is quite steady. “节奏”非常稳定。 Just very slow... 只是很慢......

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. 这不应该是必要的,但它无法忍受......我当然仍然非常期待一个正确的解决方案。

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 Project select your target 转到Project选择目标
  2. Build Settings -> Swift Compiler - Custom Flags Build Settings - > Swift Compiler - Custom Flags
  3. Add to Other Swift Flags -Xfrontend -warn-long-function-bodies=50 (50 represent the time in milliseconds) 添加到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'花了108ms进行类型检查(限制:50ms)

and after that you know what to do ;) 之后你知道该怎么做;)

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以来,我遇到了同样的问题,它似乎是由大数组文字引起的,类似于

I was able to fix the issue by adding type annotations to the variables being assigned to the array literal, eg 我能够通过向分配给数组文字的变量添加类型注释来解决问题,例如

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

instead of 代替

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

This is an issue with Xcode 8 where it does not perform incremental builds correctly. 这是Xcode 8的一个问题,它不能正确执行增量构建。 If you edit a single swift file it should compile only that file only. 如果您编辑单个swift文件,它应该只编译该文件。 This has already been raised here: Xcode 8 does full project rebuild 这已经在这里提出: Xcode 8完成了完整的项目重建

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正在执行项目的完全重建,如果您只在一个文件中修改了一行,则不应该再次发生。

In my case I was using a helper function to save some data in Firebase. 在我的情况下,我使用辅助函数来保存Firebase中的一些数据。 That function was returning a dictionary with about 20 elements and it would take about 40 mins to compile. 该函数返回一个包含大约20个元素的字典,编译大约需要40分钟。 My solution was to initialize an empty dictionary and then add the items one by one to someDict . 我的解决方案是初始化一个空字典,然后将这些项逐个添加到someDict Now it compiles in less than 30 seconds. 现在它在不到30秒的时间内编译。 I hope it helps. 我希望它有所帮助。

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
}

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.. 在左侧列中选择Build并取消选中“Find implicit dependencies”但是在第一次构建项目时应保持选中此标志。

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. 对于我的一个较大的项目(42个文件),它从2:36减少到2:20。 Then I added: SWIFT_WHOLE_MODULE_OPTIMIZATION = YES to Build Settings as a user defined setting. 然后我添加了:SWIFT_WHOLE_MODULE_OPTIMIZATION = YES将Build Settings设置为用户定义的设置。 The time went down to - 2:00 时间下降到凌晨2点

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.. 在左侧列中选择Build并取消选中“Find implicit dependencies”但是在第一次构建项目时应保持选中此标志。

and the build took 7 seconds. 并且构建需要7秒。

I hope this helps. 我希望这有帮助。

I was able to greatly reduce my swift project compile times by avoiding the use the Nil-Coalescing Operator and string concatenation. 通过避免使用Nil-Coalescing运算符和字符串连接,我能够大大减少我快速的项目编译时间。

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秒。

Make sure you're not combining arrays like let combinedArrays = array1 + array2 . 确保你没有像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 combinedArrays should be. 这里有类型推断的已知错误,其中Swift浪费时间试图找出combinedArrays应该是什么类型。 Instead, [array1, array2].joined() should work just as well, and compile far faster. 相反, [array1, array2].joined()应该也可以正常工作,编译得更快。

One common practice that slows down compile time is using Array.append and String.append (or their + operator equivalents). 减慢编译时间的一种常见做法是使用Array.appendString.append (或它们的+运算符等价物)。 For String s, it's better to use a formatted string, so instead of 对于String ,最好使用格式化的字符串,而不是

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. 我不记得确切的加速,但对于那些特定的线,它大约是10次。 Odds are, thought, that this won't have a noticeable speedup for any but the tinest projects. 可以想象,除了最重要的项目之外,这种情况不会有明显的加速。 For example, our project has hundreds of 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 . 例如,我们的项目有数百个 Swift文件,以及许多Objective-C文件,我们的编译时间通常是10分钟或更长时间, 有时甚至是唯一的更改是非Swift文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM