web-dev-qa-db-fra.com

Xcode 6 avec Swift dactylographie très lente et autocomplétion

Est-ce juste moi ou Xcode 6 (6.0.1) avec Swift semble être super lent lorsque vous tapez votre code, en particulier avec l'auto-complétion?

Une classe Objective-C normale, même à l’intérieur d’un projet Swift, fonctionne presque de la même manière qu’auparavant, elle est donc Swift qui la tue).

Est-ce que quelqu'un d'autre rencontre le même inconvénient? Avez-vous une idée de la façon d'améliorer les performances?

  • J'ai essayé de jouer avec quelques réglages mais pas de chance.
  • J'ai aussi bien sûr essayé de redémarrer Xcode et l'ordinateur sans succès.
  • Aucune autre application lourde n'est ouverte.

J'utilise un Macbook Pro de la mi-2009 (Intel Core 2 Duo à 2,26 GHz) avec 8 Go RAM et SSD HD, qui n'est pas la dernière nouveauté du tout, mais pas tout à fait indésirable.

C’est dommage car j’étais excité de commencer à utiliser Swift) et c’est maintenant vraiment insupportable.

Pensées/conseils?

112
mllm
  • Quitter Xcode et redémarrer le Mac ne sont pas obligatoires mais préférés.
  • Supprimez le conten du dossier ~/Library/Developer/Xcode/DerivedData
  • Supprimer le conten ~/Library/Caches/com.Apple.dt.Xcode

Ceci est une solution temporelle, mais fonctionne grandement.

Ci-dessous le script utilisant l'application Script Editor.

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

Alternativement, vous pouvez créer un alias pour votre terminal comme ceci:

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

Vous pouvez ajouter cela à votre ~/.bash_profile puis tapez xcodeclean sur la ligne de commande chaque fois que vous souhaitez effacer ces deux dossiers.

J'ai également expérimenté 100% + CPU en tapant du code "simple". Quelques petites astuces pour rendre Swift-parser plus rapide en structurant votre code.

N'utilisez pas le "+" concatinateur dans les chaînes. Pour moi, cela déclenche la lenteur très rapidement. Chaque nouveau "+" amène l'analyseur à une analyse, et il doit analyser le code chaque fois que vous ajoutez un nouveau caractère quelque part dans le corps de votre fonction.

Au lieu de:

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

Utilisez la syntaxe de modèle qui semble beaucoup plus efficace à analyser dans Swift:

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

De cette façon, je ne remarque pratiquement pas de limite dans strlen avec les vars en ligne "\ (*)".

Si vous avez des calculs, utilisez +/* - puis divisez-les en parties plus petites.

Au lieu de:

var result = pi * 2 * radius 

utilisation:

var result  = pi * 2
    result *= radius

Cela peut sembler moins efficace, mais l’analyseur Swift est beaucoup plus rapide de cette façon. Certaines formules ne compileront pas si elles comportent plusieurs opérations, même si elles sont mathématiquement correctes.

Si vous avez des calculs complexes, mettez-les dans une fonction. De cette façon, l'analyseur peut l'analyser une fois et n'a pas à le réparer à chaque fois que vous modifiez quelque chose dans votre corps de fonction.

Parce que si vous avez un calcul dans votre corps de fonction, l'analyseur Swift le vérifie à chaque fois si les types, la syntaxe, etc. sont toujours corrects. Si une ligne change au-dessus du calcul, il est possible que certains vars de votre calcul/formule aient changé. Si vous le mettez dans une fonction externe, il sera validé une fois et Swift se contente de son exactitude et ne le répare pas en permanence, ce qui entraîne une utilisation intensive du processeur.

De cette façon, je suis passé de 100% sur chaque pression de touche à un processeur faible pendant la frappe. Par exemple, ces 3 lignes insérées en ligne dans votre corps de fonction peuvent amener le swiftparser à une analyse.

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 )

mais si je le mets dans une fonction et l'appelle plus tard, swiftparser est beaucoup plus rapide

// 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 et XCode 6.1 sont toujours très bogués, mais si vous suivez ces astuces simples, le code d’édition redevient acceptable. Je préfère Swift beaucoup, car il se débarrasse des fichiers .h et utilise une syntaxe beaucoup plus propre. De nombreux types de saisie de type sont encore nécessaires, tels que "myVar as AnyObject", mais c'est le plus petit mal comparé à la structure et à la syntaxe complexes du projet objective-c.

Autre expérience également, j’ai essayé le SpriteKit, qui est amusant à utiliser, mais assez inefficace si vous n’avez pas besoin de repeindre en permanence à 60 images par seconde. Utiliser de vieux CALayers est bien meilleur pour le processeur si vos "sprites" ne changent pas aussi souvent. Si vous ne modifiez pas le contenu des couches, alors le processeur est essentiellement inactif, mais si vous avez une application SpriteKit exécutée en arrière-plan, alors vidéoplayback dans d'autres applications pourrait commencer à bégayer en raison de la boucle de mise à jour à 60fps très limitée.

Parfois, xcode affiche des erreurs étranges lors de la compilation, puis il est utile d’aller dans le menu "Produit> Nettoyer" et de le recompiler, ce qui semble être une implémentation erronée du cache.

Un autre excellent moyen d’améliorer l’analyse lorsque xcode se coince avec votre code est mentionné dans une autre publication stackoverflow ici . En gros, vous copiez tout le contenu de votre fichier .Swift dans un éditeur externe, puis, fonction par fonction, recopiez-le et voyez où se trouve votre goulot d'étranglement. Cela m'a en fait aidé à obtenir à nouveau une vitesse raisonnable pour xcode, après que mon projet soit devenu fou avec 100% de CPU. tout en recopiant votre code, vous pouvez le reformuler et essayer de garder vos corps de fonction courts et vos fonctions/formules/expressions simples (ou scindées en plusieurs lignes).

13
Daniel Unterberger

La saisie semi-automatique est interrompue depuis Xcode 4. Jusqu'au Apple décide de corriger ce bogue âgé de 2 ans, la seule solution, malheureusement, consiste à désactiver l'achèvement de code OFF sur les préférences de XCode (première option de la photo ci-dessous).

Vous pouvez continuer à compléter manuellement en tapant CTRL space ou ESC lorsque vous en avez besoin.

C'est la seule solution qui fonctionne à chaque fois pour 100% des cas.

enter image description here

Une autre chose que j'ai découverte récemment est la suivante: si vous utilisez des plugins sur Xcode, ne le faites pas. Retirez-les tous. Ils aggravent le problème.

10
SpaceDog

Utilisez-vous Spotify? J'ai installé Yosemite GM avec Xcode 6.1 GM sur un iMac mi-2009 (2.66Ghz) ayant le même problème. J'ai également constaté qu'un processus appelé "SpotifyWebHelper" était toujours marqué en rouge comme ne répondant pas, j'ai donc désactivé l'option "démarrer à partir du Web" dans Spotify et maintenant, Xcode semble fonctionner beaucoup mieux.

5
Eugenio Baglieri

En règle générale, le déplacement du dossier de cache (DerivedData) sur un lecteur SSD (en particulier dans mon cas - un stockage externe connecté à la sortie Thunderbolt) a considérablement amélioré les performances de mon Xcode. Le temps de compilation et les interrogations générales autour de l'application sont environ 10 fois plus rapides .. Également déplacé l'ensemble du dossier git sur le disque SSD, ce qui a considérablement amélioré les performances de git.

2
brkeyal

Réduire toutes les méthodes aide un peu.

commande-alt-shift-flèche à gauche fera l'affaire ...

Pour plier/déplier les méthodes actuelles ou si les structures utilisent:

Fold: Commande-Alt-Gauche

Déplier: Commande-Alt-Droite

2
rowdyruckus

C'était une douleur jusqu'à XCode 7.2.

Apple l'a corrigé dans XCode 7.3 et cela fonctionne maintenant comme un charme. C'est super rapide et beaucoup plus puissant, car cela semble fonctionner un peu comme la recherche floue de fichiers: vous n'avez pas besoin de taper le début exact de la méthode/propriété pour que celle-ci apparaisse dans la liste des propositions.

2
Bioche

J'ai eu les mêmes problèmes, même dans Xcode 6.3

  • autocompletions super lent
  • indexation très lente
  • énorme utilisation du processeur par Swift et SourceKitService
  • énorme utilisation de la mémoire par SourceKitService

Tout cela se passait même dans un projet relativement petit. J'ai essayé tous les correctifs que j'ai pu trouver:

  • supprimer ~/Library/Developer/Xcode/DerivedData/*
  • supprimer ~/Library/Caches/com.Apple.dt.Xcode/*
  • supprimer tous les "+" chaînes combinant du code
  • supprimé toutes les déclarations de dictionnaire suspectes

Aucun de ceux-ci n'a réellement contribué à mon projet.

Ce qui résolut réellement mon problème était:

  • placer chaque fin chaque classe dans son propre fichier
  • placer chaque extension dans son propre fichier (Class + ExtName.Swift)
  • placer "out of class Swift") dans son propre fichier

Maintenant, j'ai une utilisation du processeur proche de zéro, une faible utilisation de la mémoire et des complétions assez rapides.

2
Matej Ukmar

J'ai eu le même problème où la dactylographie était à la traîne dans une classe particulière et se trouve que

/* Long multiline comments */

ralentissait la dactylographie.

1
Aziz Akgul

J'ai découvert que cela se produit généralement lorsque vous:

  • avoir de longues expressions dans une seule déclaration (voir cette réponse )
  • mélanger plusieurs opérateurs personnalisés dans une seule expression

Le second cas semble être corrigé dans l'une des dernières versions de xcode. Exemple: J'ai défini 2 opérateurs personnalisés <&&> et <||>, et utilisé dans une expression comme a <&&> b <&&> c <||> d. Le fractionnement en plusieurs lignes a résolu le problème:

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

J'espère que vos cas sont couverts par l'un des 2 ci-dessus ... s'il vous plaît poster un commentaire soit le cas

1
Antonio

SourceKitService est aussi un peu maladroit pour traiter les commentaires dans le code et le commentaires incorporés le ralentir aussi.

donc, si vous pouvez vous permettre d’enlever l’énorme quantité de commentaires incorporés comme ceci:

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

cela peut certainement aider aussi.


NOTE: dans mon cas, mon Xcode 7.3.1 (7D1014) a été littéralement bloqué moi en tapant n'importe quelle lettre lorsque le fichier contenait environ 700 lignes de commentaires avec commentaires intégrés. Au départ, j'ai retiré ce bloc de cette .Swift fichier et Xcode est redevenu vivant. J'ai essayé d'ajouter mes commentaires, partie par partie, en supprimant les commentaires incorporés, c'était toujours plus lent que d'habitude, mais les performances étaient nettement meilleures s'il n'y avait pas de commentaires incorporés.

1
holex