具有 Swift 超慢键入和自动完成功能的 Xcode 6

只有我或 Xcode 6(6.0.1)与 Swift 似乎是 超级慢当您输入您的代码,特别是与自动完成?

A normal Objective-C class, even if inside a Swift project, works almost the same as before, so it's Swift that kills it.

Does anyone else experience the same inconvenience? Do you have any idea of how to improve performance?

  • 我尝试了一些设置,但没有运气。
  • 当然,我也试过重新启动 Xcode 和计算机,但没有成功。
  • 没有其他重的 apps are open.

我使用的是2009年中期的 Macbook Pro (2.26 GHz Intel 酷睿2 Duo) ,配有8GB 内存和固态硬盘,这并不是最新的东西,但也不是一个完全的垃圾。

这是一个耻辱,因为我很兴奋地开始使用 Swift,现在它是真的难以忍受。

有什么想法或建议吗?

23082 次浏览

I found out that usually happens when you:

  • 在单个语句中使用长表达式(参见 这个答案)
  • 在单个表达式中混合多个自定义运算符

The 2nd case seems to be fixed in one of the latest xcode releases. Example: I defined 2 custom operators <&&> and <||>, and used in an expression like a <&&> b <&&> c <||> d. Splitting to multiple lines solved the problem:

let r1 = a <&&> b
let r2 = r1 <&&> c
let r3 = r2 <||> d

我希望你的情况是涵盖以上2... 请发表评论任何情况

你在用 Spotify 吗? 我在2009年年中(2.66 Ghz)的 iMac 上安装了 Xcode 6.1 GM 的 Yosemite GM,发现同样的问题。我发现一个叫做“ SpotifyWebHelper”的进程总是被标记为没有响应,所以我在 Spotify 中禁用了“从 web 开始”的选项,现在 Xcode 似乎运行得更好了。

在输入一些“简单”代码时,我也体验到了100% + CPU。通过构造代码的方式,使迅速解析器更快的一些小技巧。

不要在字符串中使用“ +”连接符。对我来说,这会很快触发缓慢。 每个新的“ +”都使解析器进入爬行状态,并且每次在函数体的某个地方添加新字符时,解析器都必须重新解析代码。

而不是:

var str = "This" + String(myArray.count) + " is " + String(someVar)

使用看起来更有效的模板语法来快速解析:

var str = "This \(myArray.count) is \(someVar)"

This way i basically notice no limit in strlen with inline vars "\(*)" .

如果您有使用 +/*-的计算,那么将它们分成更小的部分。

而不是:

var result = pi * 2 * radius

用途:

var result  = pi * 2
result *= radius

这样看起来可能效率较低,但是快速解析器在这方面要快得多。 有些公式无法编译,如果它们有许多操作,即使它们在数学上是正确的。

如果你有一些复杂的计算,然后把它放在一个 func。这样解析器就可以解析它一次,而不必在每次更改函数体中的内容时重新解析它。

因为如果在函数体中有一个计算,那么如果类型、语法等仍然正确,那么快速解析器就会每次都进行检查。如果一条直线在计算之上发生了变化,那么计算/公式中的一些变量可能已经发生了变化。如果你把它放在一个外部函数中,那么它将被验证一次,而且迅速很高兴它是正确的,不会不断重新解析它,这导致了高 CPU 使用率。

这样,我得到了从100% 的每个按键低 CPU 而打字。 例如,在函数体中内联的这3行代码可以使迅速解析器变得异常缓慢。

let fullPath =  "\(NSHomeDirectory())/Library/Preferences/com.apple.spaces.plist"
let spacesData  = NSDictionary(contentsOfFile: fullPath )! // as Dictionary<String, AnyObject>
let spaces : AnyObject   = spacesData["SpacesDisplayConfiguration"]!["Management Data"]!!["Monitors"]!![0]["Spaces"]!!


println ( spaces )

但是如果我把它放到一个函数里,然后再叫它,Swift 语法分析器会快很多

// some crazy typecasting here to silence the parser
// Autodetect of Type from Plist is very rudimentary,
// so you have to teach swift your types
// i hope this will get improved in swift in future
// would be much easier if one had a xpath filter with
// spacesData.getxpath( "SpacesDisplayConfiguration/Management Data/Monitors/0/Spaces" ) as Array<*>
// and xcode could detect type from the plist automatically
// maybe somebody can show me a more efficient way to do it
// again to make it nice for the swift parser, many vars and small statements
func getSpacesDataFromPlist() -> Array<Dictionary<String, AnyObject>> {
let fullPath =  "\(NSHomeDirectory())/Library/Preferences/com.apple.spaces.plist"


let spacesData  = NSDictionary(contentsOfFile: fullPath )!    as Dictionary<String, AnyObject>
let sdconfig    = spacesData["SpacesDisplayConfiguration"]    as Dictionary<String, AnyObject>
let mandata     = sdconfig["Management Data"]                 as Dictionary<String, AnyObject>
let monitors    = mandata["Monitors"]                         as Array<Dictionary<String, AnyObject>>
let monitor     = monitors[0]                                 as Dictionary<String, AnyObject>
let spaces      = monitor["Spaces"]                           as Array<Dictionary<String, AnyObject>>


return spaces
}


func awakeFromNib() {
....
... typing here ...


let spaces = self.getSpacesDataFromPlist()
println( spaces)
}

Swift 和 XCode 6.1仍然存在很多 bug,但是如果遵循这些简单的技巧,编辑代码就又可以接受了。我更喜欢迅速,因为它可以摆脱。H 文件,并使用更清晰的语法。仍然需要许多类型转换,比如“ myVar as AnyObject”,但是与复杂的 Objective-c 项目结构和语法相比,这种转换的弊端要小得多。

另一个经验,我尝试了 SpriteKit,这是很有趣的使用,但它的效率相当低,如果你不需要一个不断重新油漆在60帧。如果你的“精灵”不经常改变的话,使用旧的 CALayers 对 CPU 来说是更好的。如果你不改变。层的内容,然后 CPU 基本上是空闲的,但是如果你有一个 SpriteKit 应用程序在后台运行,然后视频播放在其他应用程序可能会开始口吃,由于硬限制60 fps 更新循环。

Sometimes xcode shows odd errors while compiling, then it helps to go into menu "Product > Clean" and compile it again, seems to be a buggy implementation of the cache.

另一个改进解析的好方法是在另一个 stackoverflow 文章 给你中提到的。基本上你复制所有的内容。快速文件到一个外部编辑器,然后通过函数功能复制回来,看看你的瓶颈在哪里。这实际上帮助我让 xcode 再次达到一个合理的速度,在我的项目因为100% CPU 而疯狂之后。在复制代码时,您可以重构它,并尝试保持函数体简短,函数/公式/表达式简单(或分成几行)。

  • 退出 Xcode 并重新启动 Mac 不是必需的,但首选。
  • 删除文件夹的 内容 库/开发者/Xcode/衍生数据
  • 删除 内容 ~/Library/Cache/com.apple.dt. Xcode

这是一个暂时的解决方案,但效果很好。

脚本下面使用脚本编辑器应用程序。

tell application "Terminal"
do script "rm -frd ~/Library/Developer/Xcode/DerivedData/*"
do script "rm -frd ~/Library/Caches/com.apple.dt.Xcode/*"
end tell

或者,您可以为您的终端创建一个别名,如下所示:

alias xcodeclean="rm -frd ~/Library/Developer/Xcode/DerivedData/* && rm -frd ~/Library/Caches/com.apple.dt.Xcode/*"

您可以将其添加到 ~/.bash_profile中,然后在每次要清除这两个文件夹时在命令行中键入 xcodeclean

自动补全程序在 Xcode 4中断。不幸的是,在苹果决定修复这个两年前的 bug 之前,唯一的解决方案是将代码完成 关掉设置为 XCode 的首选项(下图的第一个选项)。

您可以继续享受完成手动键入 CTRL spaceESC时,您需要它。

这是唯一的解决方案,每次工作的100% 的情况下。

enter image description here

我最近发现的另一件事是: 如果你在 Xcode 上使用插件,不要使用。把他们都带走。他们让问题更严重了。

我在 Xcode 也有同样的问题

  • 超慢的自动补全
  • 超级慢的索引
  • 迅速和 SourceKitService 的巨大 CPU 使用量
  • enormous Memory usage by SourceKitService

所有这些都发生在相对较小的项目中,我尝试了所有我能找到的修复方法:

  • 正在删除 ~/Library/Developer/Xcode/deriedData/*
  • 正在删除 ~/Library/Cache/com.apple.dt. Xcode/*
  • remove all "+" String combining from the code
  • 删除所有可疑的字典声明

这些实际上对我的项目都没有帮助。

真正解决我问题的是:

  • 将每个类的每一端放在它自己的文件中
  • placing each and every extension in its own file (Class+ExtName.swift)
  • 在自己的文件中放置“课外快速方法”

现在我的 CPU 使用率接近于零,内存使用率较低,完成速度相当快。

一般来说,将缓存文件夹(衍生数据)移动到 SSD 驱动器(特别是在我的情况下——连接到 Thunderbolt 出口的外部存储器)极大地提高了我的 Xcode 性能。.编译时间和围绕应用程序的一般疑问大约快10倍。.还将整个 git 文件夹移动到 SSD,这极大地提高了 git 性能。

直到 XCode 7.2之前都很痛苦。

苹果公司在 XCode 7.3中修复了它,现在它工作起来像魔法一样。它的速度非常快,而且功能强大得多,因为它的工作方式有点像文件的模糊搜索: 您不必实际输入方法/属性的确切开头,它就会出现在命题列表中。

折叠所有方法有一点帮助。

命令-Alt-shift-left 箭头就可以了。

折叠/展开当前的方法或如果结构使用:

折叠: command-alt-left 箭头

展开: command-alt-right 箭头

SourceKitService在处理代码中的注释时也有点笨拙,而 嵌入式评论也会降低它的速度。

因此,如果你能承担得起删除大量嵌入式评论的费用,比如:

/*
* comment
/*
* embedded comment
*/
*/

肯定也有帮助。


注意: 在我的例子中,我的 Xcode 7.3.1(7D1014)实际上阻止我输入任何字母,当文件有大约700行带有嵌入注释的注释时。最初,我从 .swift文件中删除了那个块,Xcode 又活了过来。我尝试通过删除嵌入式注释来一部分一部分地添加我的注释,它仍然比平常慢,但是如果没有嵌入式注释,它显示出明显更好的性能。

我遇到过同样的问题,在某个特定的类中输入是滞后的,结果是

/* 很长 multiline 评论 */

减慢了打字的速度。