Xcode 6 con Swift super lenta tipificación y autocompletado

¿Es solo que yo o Xcode 6 (6.0.1) con Swift parece ser súper lento cuando escribes tu código, especialmente con autocompletado?

Una class normal de Objective-C, incluso si está dentro de un proyecto Swift, funciona casi igual que antes, por lo que es Swift la que lo mata.

¿Alguien más experimenta el mismo inconveniente? ¿Tienes alguna idea de cómo mejorar el performance?

  • Traté de jugar con algunos ajustes pero no tuve suerte.
  • También, por supuesto, intenté reiniciar Xcode y la computadora sin suerte.
  • No hay otras aplicaciones pesadas abiertas.

Utilizo un Macbook Pro de mediados de 2009 (Intel Core 2 Duo de 2,26 GHz) con 8 GB de RAM y SSD HD, que no es lo más nuevo, pero aún no es una basura completa.

Es una lástima porque estaba emocionado de comenzar a usar Swift y ahora es realmente insoportable.

Pensamientos / consejos?

  • Salir de Xcode y reiniciar la Mac no es obligatorio pero se prefiere.
  • Eliminar el contenido de la carpeta ~ / Library / Developer / Xcode / DerivedData
  • Eliminar el contenido ~ / Library / Caches / com.apple.dt.Xcode

Esta es una solución temporal, pero funciona mucho.

Debajo del script usando la aplicación 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 

Alternativamente, puede crear un alias para su terminal como este:

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

Puedes agregar eso a tu ~/.bash_profile y luego escribir xcodeclean en la línea de command cada vez que desees borrar esas dos carpetas.

También experimenté 100% + CPU mientras escribía un código "simple". Algunos pequeños trucos para hacer que el analizador rápido sea más rápido por la forma en que estructura su código.

No use el concatinador "+" en cadenas. Para mí esto desencadena la lentitud muy rápidamente. Cada nuevo "+" trae al analizador a un rastreo, y tiene que volver a comstackr el código cada vez que agrega un nuevo carácter en alguna parte de su cuerpo de funciones.

En lugar de:

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

Utilice la plantilla-syntax que parece mucho más eficiente para analizar de manera rápida:

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

De esta manera, básicamente, noto que no hay límite en strlen con vars en línea "\ (*)".

Si tiene cálculos, que usan + / *, entonces divídalos en partes más pequeñas.

En lugar de:

 var result = pi * 2 * radius 

utilizar:

 var result = pi * 2 result *= radius 

Puede parecer less eficiente, pero el analizador rápido es mucho más rápido de esta manera. Algunas fórmulas no se comstackrán, si tienen muchas operaciones, incluso si son matemáticamente correctas.

Si tiene algunos cálculos complejos, póngalo en una function. De esta forma, el analizador puede analizarlo una vez y no debe repararlo cada vez que cambia algo en su cuerpo de function.

Porque si tiene un cálculo en su cuerpo de function, de alguna manera el analizador rápido lo verifica cada vez si los types, la syntax, etc. siguen siendo correctos. Si una línea cambia por encima del cálculo, entonces algunas vars dentro de su cálculo / fórmula podrían haber cambiado. Si lo pone en una function externa, será validado una vez y Swift está contento de que será correcto y no lo repara constantemente, lo que está causando un alto uso de la CPU.

De esta forma, obtuve del 100% en cada pulsación de tecla a CPU baja mientras escribo. Por ejemplo, estas 3 líneas puestas en línea en su cuerpo de function pueden hacer que el swiftparser se rastree.

 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 ) 

pero si lo pongo en una function y lo llamo más tarde, swiftparser es mucho más rápido

 // 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 y XCode 6.1 todavía son muy cochambrosas, pero si sigues estos trucos simples, el código de edición vuelve a ser aceptable. Prefiero mucho rápido, ya que se deshace de los files .h y usa una syntax mucho más limpia. Todavía hay muchos types de casting necesarios como "myVar como AnyObject", pero ese es el mal más pequeño en comparación con la estructura y la syntax complejas del proyecto objective-c.

También otra experiencia, probé el SpriteKit, que es divertido de usar, pero es bastante eficiente si no necesitas una repintura constante a 60 fps. Usar viejos CALayers es mucho mejor para la CPU si sus "sprites" no cambian tan seguido. Si no cambia los contenidos de las capas, entonces la CPU está básicamente inactiva, pero si tiene una aplicación SpriteKit en segundo plano, la videoplayback en otras aplicaciones podría comenzar a tartamudear debido al bucle de actualización de 60 fps, que es muy limitado.

A veces xcode muestra errores extraños mientras se comstack, luego ayuda a entrar en el menu "Producto> Limpiar" y comstackrlo nuevamente, parece ser una implementación incorrecta del caching.

Otra excelente forma de mejorar el análisis cuando xcode se queda atascado con su código se menciona en otra publicación stackoverflow aquí . Básicamente, copy todos los contenidos de su file .swift en un editor externo, y luego, por function, vuelve a copyrlo y ve dónde está su cuello de botella. Esto realmente me ayudó a get xcode a una velocidad razonable otra vez, después de que mi proyecto se volvió loco con el 100% de CPU. mientras copy su código, puede refactorizarlo e intentar mantener su function, los cuerpos cortos y las funciones / formulaciones / expresiones simples (o dividirse en varias líneas).

La autocomplete se interrumpe desde Xcode 4. Hasta que Apple decide corregir este error de 2 años, la única solución, desafortunadamente, es apagar el código en las preferences de XCode (primera opción de la image a continuación).

Puede continuar disfrutando la finalización manualmente escribiendo el CTRL space o ESC cuando lo necesite.

Esta es la única solución que funciona en todo momento para el 100% de los casos.

introduzca la descripción de la imagen aquí

Otra cosa que he descubierto recientemente es: si usas complementos en Xcode, no lo hagas. Eliminarlos a todos. Empeoran el problema

¿Estás usando Spotify? Instalé Yosemite GM con Xcode 6.1 GM en un iMac a mediados de 2009 (2.66Ghz) con el mismo problema. Descubrí que un process llamado "SpotifyWebHelper" siempre está marcado en rojo porque no responde, por lo que deshabilité la opción "inicio desde la web" en spotify y ahora Xcode parece funcionar significativamente mejor.

Tuve los mismos problemas incluso en Xcode 6.3

  • autocompletaciones súper lentas
  • indexing súper lenta
  • uso enorme de CPU por Swift y SourceKitService
  • Uso de memory enorme por SourceKitService

Todo esto sucedía incluso en un proyecto relativamente pequeño. Probé todas las soluciones que pude encontrar:

  • suprimiendo ~ / Library / Developer / Xcode / DerivedData / *
  • suprimiendo ~ / Library / Caches / com.apple.dt.Xcode / *
  • Eliminar todos los "+" String combinando del código
  • eliminó todas las declaraciones de dictionary sospechosas

Ninguno de estos realmente ayudó en mi proyecto.

Lo que realmente resolvió mi problema fue:

  • colocando cada extremo en cada class en su propio file
  • colocando cada extensión en su propio file (Class + ExtName.swift)
  • colocando "methods rápidos de class" en su propio file

Ahora tengo casi cero uso de CPU, bajo uso de memory y decentemente rápido finalizaciones.

En general, mover la carpeta de caching (DerivedData) a una unidad SSD (específicamente en mi caso, un almacenamiento externo conectado a la salida de Thunderbolt) ha mejorado drásticamente mi performance de Xcode. El time de compilation y las preguntas generales alnetworkingedor de la aplicación son aproximadamente 10 veces más rápidas. También movió toda la carpeta git al SSD, lo que mejoró drásticamente el performance de git.

Fue un dolor hasta XCode 7.2.

Apple lo arregló en XCode 7.3 y ahora funciona como un encanto. Es súper rápido y mucho más potente, ya que parece funcionar un poco como la búsqueda difusa de files: no es necesario que escriba el principio exacto del método / propiedad para que aparezca en la list de proposiciones.

El queuepso de todos los methods ayuda un poco.

command-alt-shift-left arrow hará el truco …

Para plegar / desplegar methods actuales o si las estructuras usan:

Fold: command-alt-left arrow

Despliegue: command-alt-right arrow

Descubrí que generalmente ocurre cuando:

  • Tener expresiones largas en una sola statement (ver esta respuesta )
  • mezclar múltiples operadores personalizados en una sola expresión

El segundo caso parece corregido en uno de los últimos lanzamientos xcode. Ejemplo: definí 2 operadores personalizados <&&> y <||>, y los utilicé en una expresión como a <&&> b <&&> c <||> d . Dividir en varias líneas resolvió el problema:

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

Espero que sus casos estén cubiertos por uno de los 2 anteriores … publique un comentario en cualquiera de los casos

SourceKitService también es un poco torpe para tratar los comentarios en el código y los comentarios embeddeds también lo ralentizan.

así que si puedes permitirte eliminar la enorme burbuja de comentarios embeddeds como esta:

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

que definitivamente puede ayudar también.


NOTA: en mi caso, mi Xcode 7.3.1 (7D1014) fue literalmente bloqueado al escribir cualquier letra cuando el file tenía cerca de 700 líneas de comentarios con comentarios embeddeds. inicialmente .swift ese bloque de ese file .swift y Xcode volvió a estar vivo. He intentado agregar mis comentarios parte por parte al eliminar los comentarios embeddeds, aún era más lento de lo habitual, pero mostró un performance significativamente mejor si no había comentarios embeddeds.

Tuve el mismo problema en el que escribir estaba retrasado en una class en particular y resulta que

/* Long multiline comments */

estaba ralentizando la tipificación.