2012-05-17 12 views
14

Estoy desarrollando mi primera gema llamada t_time_tracker (woohoo!). Todo iba muy bien en desarrollo; Me optomized tanto como me sea posible para reducir el tiempo de ejecución hasta tan poco como sea posible:¿Por qué mi gema tarda tanto en cargarse?

t_time_tracker[master*]% time ruby -Ilib ./bin/t_time_tracker 
You're not working on anything 
0.07s user 0.03s system 67% cpu 0.141 total 

(este es el "hola mundo" de mi aplicación - llamándolo sin parámetros se limita a imprimir "Usted' no está trabajando en nada ")

Aproximadamente una décima de segundo y utiliza el 67% de mi CPU - Genial, puedo vivir con eso. Se siente bastante instantáneo. Construyamos que:

$ gem build t_time_tracker.gemspec 
$ gem install ./t_time_tracker-0.0.0.gem 

y hacer exactamente lo mismo con el binario instalado:

$ time t_time_tracker 
You're not working on anything 
t_time_tracker 0.42s user 0.06s system 93% cpu 0.513 total 

Medio segundo ?! ¡¿De donde vino eso?! Vamos a añadir un poco de salida de depuración e incluyen la gema del sistema binario de desarrollo para ver donde el cuello de botella es:

t_time_tracker[master*]% time ruby ./bin/t_time_tracker 
(starting binary) 
(require 'time' and 'optparse') 
0.041432 
(before `require 't_time_tracker') 
0.497135 
(after `require 't_time_tracker') 
(Gem.loaded_specs.keys = t_time_tracker) 
(initializing TTimeTracker class) 
You're not working on anything 
ruby ./bin/t_time_tracker 0.44s user 0.07s system 91% cpu 0.551 total 

bien, por lo que la línea `requerir 't_time_tracker' parece ser el culpable. Intentémoslo nuevamente en irb para reducirlo aún más:

$ irb 
>> t=Time.now; require 't_time_tracker'; puts Time.now-t 
0.046792 
=> nil 

... what? ¡Pero eso solo tomó medio segundo! Vamos a intentar la construcción de la joya con nuestra salida de depuración:

$ gem build t_time_tracker.gemspec 
$ gem install ./t_time_tracker-0.0.0.gem 
$ time t_time_tracker 
(starting binary) <---noticeable half second delay before this line shows up 
(require 'time' and 'optparse') 
0.050458 
(before `require 't_time_tracker') 
0.073789 
(after `require 't_time_tracker') 
(Gem.loaded_specs.keys = t_time_tracker) 
(initializing TTimeTracker class) 
You're not working on anything 
t_time_tracker 0.42s user 0.06s system 88% cpu 0.546 total 

Así que sí, ¿dónde está el retardo de 0.5 segundos viene? Por lo general, no me importa, pero esto es algo a lo que llamo unas cincuenta veces al día para actualizar lo que estoy haciendo. 50 * 0.5 segundos * 365 días * 70 años = 15 días de vida perdida.

Información del sistema:

Mac OS X 10.7.3. 2 GHz Intel Core 2 Duo. 4 GB de ram. ruby 1.9.2p290.

% gem -v 
1.8.10<---noticeable half second delay before this line shows up 
% gem list | wc -l 
209 
+3

¿Cómo es el rendimiento en 1.9.3? –

+0

Interesante ... 'rvm 1.9.3 && gem install t_time_tracker' me da de nuevo mi tiempo de ejecución superrápido (0.100 segundos en total), pero sospecho que esto es solo porque' gem list | wc -l' = 7. Hmmm ... – cgenco

+0

Después de 'gem install rails',' gem list | wc -l' = 33, y 'tiempo t' es un promedio de aproximadamente 0.21. ¿La solución es simplemente "no instalar muchas gemas"? – cgenco

Respuesta

2

ha pasado un tiempo desde que miraba esto, pero RubyGems ha, en el pasado (y tal vez el presente), llevado mucho tiempo para cargar por dos razones principales:

  • sería cargar muchas bibliotecas relativamente caros como 'tiempo' a través de 'yaml'. Por lo general, no te importa porque es lento en relación con el rubí por sí solo, no es lento en comparación con el tiempo de ejecución de muchos scripts.
  • Escanearía todas las gemas instaladas y cargaría las gemspecs más recientes en la memoria. Esto llevó mucho tiempo si tienes muchas gemas.

Estos problemas pueden o no estar todavía en juego. Sin embargo, tendrá siempre con algunos gastos generales de RubyGems. Si realmente necesita rendimiento, ¡simplemente configure su ruta de carga usted mismo! Ruby sin RubyGems es muy rápido, como sabes.

para ver donde está instalado su joya:

gem list -d YOUR_GEM_NAME 

verás el directorio de instalación. Su joya estará en INSTALL_DIR/joyas/GEM_NAME-VERSIÓN a fin de tratar de ejecutar:

time ruby -IINSTALL_DIR/gems/GEM_NAME-VERSION/lib INSTALL_DIR/gems/GEM_NAME-VERSION/bin/t_time_tracker 

Eso es mucho, pero usted debe ser capaz de terminar con esto en una secuencia de comandos independiente, algo como esto (nombre que t_time_tracker):

#!/usr/bin/env ruby -IINSTALL_DIR/gems/GEM_NAME-VERSION/lib 
load 'INSTALL_DIR/gems/GEM_NAME-VERSION/bin/t_time_tracker' 

continuación:

chmod +x t_time_tracker 
time ./t_time_tracker 

y poner ese archivo en cualquier lugar a lo largo de su PATH. RubyGems hace por usted automáticamente, pero por supuesto acepta los gastos generales de RubyGems.

+0

genial, pero ¿qué tal una gema que se está distribuyendo a otros usuarios? – sixty4bit

0

Probablemente es porque lo tiene "de local" joya. Entonces Ruby tendrá que verificar otros caminos antes de que él lo recoja.

por ejemplo. si va a tener archivo llamado json.rb y joya instalada a nivel mundial llamada JSON al hacer

require 'json' 

se encontrará primera gema y cargarlo :). La ruta local es la última en cargarse. Si empacas la gema e instalas verás una gran mejora de velocidad solo por la diferente ubicación en las gemas. No me preocuparía mucho esta falta de tiempo de carga en el desarrollo.

0

El $LOAD_PATH que se utiliza dentro de su gema es probable que sea el culpable. Lo ideal es que la ruta de su carpeta lib esté primero en esa matriz.

Cuestiones relacionadas