Xcode 6 with Swift super slow typing and autocompletion
Asked Answered
D

11

115

Is it just me or Xcode 6 (6.0.1) with Swift seems to be super slow when you type your code, especially with autocompletion?

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?

  • I tried to play with some settings but no luck.
  • I've also of course tried restarting Xcode and the computer with no luck.
  • No other heavy apps are open.

I use a Mid 2009 Macbook Pro (2.26 GHz Intel Core 2 Duo) with 8GB RAM and SSD HD, which is not the newest thing at all, but still not a complete junk.

It is a shame as I was excited to start using Swift and it is now really unbearable.

Thoughts / tips?

Davit answered 20/9, 2014 at 10:58 Comment(10)
I'm having the same issues as you. Often Xcode tells me "SourceKit terminated, editor temporarily limited"Lines
Yeah, this is also another problem, I'm not sure they're related though. It was slow even when that error is happening.Davit
I'm sure they are related. In beta 5 I saw that message even more often, and I saw that anytime when the suggestion did not work. (When I typed some chars and pressed Esc to trigger the suggestion)Lines
Well there are many posts around about this "sourceKit terminated" issue, I'll try them to see if it also solves the sluggish problem.Davit
I have the same problem. My XCode uses 300%+ of the CPU and slows my macbook retina down to a snail speed. I pretty much type blindly this days and wait for xcode to complete.Cote
Tried with a newer Mac Mini (i5) and it worked as normal, responsive like back with Obj C. Is it REALLY a performance issue?? Is Apple really expecting us to upgrade our computers now in order to use Swift?Davit
Having the same problems with a late 2011 15.6" MacBook Pro with 8 GB RAM and an SSD. 90% of the time code completion freezes Xcode, when I check the activity monitor I see ~200% CPU usage. Freezes last from a couple seconds to a couple minutes.Prefab
In Xcode 6.1 the freezes were replaced by constant crashing of SourceKit.Prefab
I just solved these issues. See my answer to this other question: https://mcmap.net/q/162542/-xcode-6-isn-39-t-autocompleting-in-swiftTriglyph
@bWlrYWphdWhvbmVu, interesting, I'll give it a try and updateDavit
R
86
  • Quit Xcode and restart the Mac are not required but preferred.
  • Delete the content of the folder ~/Library/Developer/Xcode/DerivedData
  • Delete the content ~/Library/Caches/com.apple.dt.Xcode

This is a temporally solution, but works greatly.

Below the script using Script Editor app.

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

Alternatively, you can create an alias for your terminal like this:

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

You can add that to your ~/.bash_profile and then type xcodeclean on the command line every time you would like to clear those two folders.

Rhizogenic answered 27/12, 2014 at 18:47 Comment(4)
Well, although it's not close to be perfect, it does look like your solution significantly improves it. I'm gonna mark is as solving, as after quite a long time this is probably the best it can get. Would be happy to hear about others... Thanks a lot!Davit
It took my laptop almost a minute to remove all content from those two folders. Indexing on Xcode now takes under 30 seconds.Iila
It didn't make my typing and autocompletion faster, but it did help me free quite a lot space from my Mac.Affiche
This answer helped on the autocompletion thing, https://mcmap.net/q/189756/-xcode-6-3-code-completion-too-slowAffiche
A
13

I also experienced 100%+ CPU while typing some "simple" code. Some small tricks to make the swift-parser quicker by the way you structure your code.

Don't use the "+" concatinator in strings. For me this triggers the slowness very quickly. Each new "+" brings the parser to a crawl, and it has to reparse the code everytime you add a new char somewhere in your function body.

Instead of:

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

Use the template-syntax which seems much more efficient to parse in swift:

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

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

If you have calculations, which use + / * - then split them into smaller parts.

Instead of:

var result = pi * 2 * radius 

use:

var result  = pi * 2
    result *= radius

It might look less efficient, but the swift parser is much faster this way. Some formulas won't compile, if they have to many operations, even if they are mathematically correct.

If you have some complex calculations then put it in a func. This way the parser can parse it once and does not have to reparse it everytime you change something in your function body.

Because if you have a calculation in your function body then somehow the swift parser checks it everytime if the types, syntax etc. are still correct. If a line changes above the calculation, then some vars inside your calculation / formula might have changed. If you put it in an external function then it will be validated once and swift is happy that it will be correct and does not reparse it constantly, which is causing the high CPU usage.

This way i got from 100% on each keypress to low CPU while typing. For example this 3 lines put inline in your function body can bring the swiftparser to a crawl.

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 )

but if i put it in a func and call it later , swiftparser is much quicker

// 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 and XCode 6.1 is still very buggy, but if you follow these simple tricks, editing code becomes acceptable again. I prefer swift a lot, as it gets rid of .h files and uses much cleaner syntax. There is still many type-casting needed like "myVar as AnyObject" , but thats the smaller evil compared to complex objective-c project structure and syntax.

Also another experience, i tried the SpriteKit, which is fun to use, but its quite in-efficient if you don't need a constant repaint at 60fps. Using old CALayers is much better for the CPU if your "sprites" don't change that often. If you don't change the .contents of the layers then CPU is basically idle, but if you have a SpriteKit app running in background, then videoplayback in other apps might start to stutter due to the hardlimited 60fps update-loop.

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.

Another great way to improve parsing when xcode gets stuck with your code is mentioned in another stackoverflow post here. Basically you copy all contents from your .swift file into an external editor, and then function by function copy it back and see where your bottleneck is. This actually helped me to get xcode to a reasonable speed again, after my project went crazy with 100% CPU. while copying your code back, you can refactor it and try to keep your function-bodies short and functions/formulars/expressions simple (or split in several lines).

Aquaplane answered 30/10, 2014 at 0:44 Comment(4)
Very thorough answer. Maybe some of the suggestions are great as "first aid", but really, don't we expect Xcode to simply work without going through a huge hassle?Davit
unfortunately xcode 6.1 + swift is quite unstable, so these “hacks” are needed. Apple should fix swift and xcode. But swift is very nice to program with, so in short-term this is the only way to keep CPU-Usage at bay.Aquaplane
i made all possible changes that you proposes but unfortunately my autocompletion still sucks.I doubt that shorthand if clauses could also make trouble.Can anyone acknowledge that ? I mean return (a == b) ? x : yEsmaria
Well, writing code in a certain way to make IDE happy is a real nonsenseConcrescence
S
10

Autocomplete is broken since Xcode 4. Until Apple decides to fix this 2 years old bug, the only solution, unfortunately, is to turn code completion OFF on XCode's preferences (first option of the pic below).

You can continue to enjoy completion manually by typing CTRL space or ESC when you need it.

This is the only solution that works every time for 100% of the cases.

enter image description here

Another thing I have discovered recently is: if you use plugins on Xcode, don't. Remove them all. They make the problem worse.

Subsidize answered 29/1, 2015 at 11:56 Comment(0)
P
5

Are you using Spotify? I installed Yosemite GM with Xcode 6.1 GM on an iMac mid 2009 (2.66Ghz) having the same problem.I found that a process called "SpotifyWebHelper" is always marked red as not responding, so i disabled the option "start from web" in spotify and now Xcode seem to run significantly better.

Pernicious answered 7/10, 2014 at 23:1 Comment(1)
Interesting, but for me it's not Spotify related... It does however show maybe that it's just a "usual" performance issue - meaning - clear more resources and it'll work better. That's sad as I haven't got anymore resources to provide (apart from money on a new mac).Davit
R
2

I found out that usually happens when you:

  • have long expressions in a single statement (see this answer)
  • mix multiple custom operators in a single expression

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

I hope that your cases is covered by one of the 2 above... please post a comment either case

Reefer answered 20/9, 2014 at 12:22 Comment(2)
Unfortunately it also happens in a brand new clean project with nothing in it and with typing something as simple as "var s : Stri...". As soon as I start typing St... it will sluggish when looking up completion suggestions.Davit
Its definitely the operands for me. Having more than one operand in the same line causes it. Thanks for the answer. This should be the right answerGaivn
P
2

I had the same issues even in Xcode 6.3

  • super slow autocompletions
  • super slow indexing
  • enormous CPU usage by swift and SourceKitService
  • enormous Memory usage by SourceKitService

All this was happening even in relatively small project. I tried all the fixes I could find:

  • deleting ~/Library/Developer/Xcode/DerivedData/*
  • deleting ~/Library/Caches/com.apple.dt.Xcode/*
  • remove all "+" String combining from the code
  • removed all suspicious dictionary declarations

None of these actually helped in my project.

What actually solved my problem was:

  • placing each end every class in its own file
  • placing each and every extension in its own file (Class+ExtName.swift)
  • placing "out of class swift methods" in its own file

Now I have close to zero CPU usage, low memory usage, and decently fast completions.

Prevost answered 23/4, 2015 at 10:14 Comment(0)
R
2

Generally, moving the cache folder (DerivedData) to a SSD drive (specifically in my case - an outer storage connected to thunderbolt exit) has dramatically improved my Xcode performance.. Compilation time and general wondering around the app is about 10 time faster.. Also moved the whole git folder to the SSD, which dramatically improved git performance.

Rayleigh answered 2/2, 2016 at 12:57 Comment(1)
Actually in the original problem I had already upgraded my mac with SSD drive and everything ran from it incl. the OS, and still there were problemsDavit
C
2

It was a pain until XCode 7.2.

Apple fixed it in XCode 7.3 and now it works like a charm. It's super fast and much more powerful as it seems to work a bit like the fuzzy search of files : you don't have to actually type the exact beginning of the method/property for it to appear in the list of propositions.

Coriss answered 6/4, 2016 at 18:17 Comment(0)
B
2

Collapsing all methods helps a little.

command-alt-shift-left arrow will do the trick...

To fold/unfold current methods or if structures use:

Fold: command-alt-left arrow

Unfold: command-alt-right arrow

Bed answered 2/8, 2016 at 9:6 Comment(0)
A
1

SourceKitService is also kinda clumsy to deal with comments in the code and the embedded comments slow it down too.

so if you can afford to remove the massive blob of embedded comments like this:

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

that can definitely help as well.


NOTE: in my case my Xcode 7.3.1 (7D1014) was literally blocked me typing any letter when the file had about 700 lines of comment with embedded comments. initially I removed that block from that .swift file and Xcode has become alive again. I tried added my comments back part by part by removing embedded comments, it was still slower than usual but it shown significantly better performance if there were no embedded comments.

Amoreta answered 9/9, 2016 at 9:6 Comment(0)
O
1

I had the same issue where typing was lagging in a particular class and turns out that

/* Long multiline comments */

was slowing down the typing.

Oversight answered 14/10, 2016 at 11:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.