8 de Julio de 2008
ruby, rails
Ilya Grigorik ha publicado un interesante post con 6 consejos para optimizar nuestro código Ruby si utilizamos el intérprete MRI.
Minimizar las búsquedas en el AST
Si utilizamos Ruby 1.8, nuestro MRI no generará bytecode. Por ello, cada llamada a un método, cada utilización de una variable, etc., realizará una búsqueda en el Abstract Syntax Tree (AST), es decir, en una estructura en árbol que representa la sintaxis de nuestro código fuente.
Debemos, por lo tanto, tener en cuenta que abusar de la metaprogramación puede hacer que el rendimiento de nuestra aplicación se vea degradado.
Optimizar para la caché
En relación con el punto anterior, para minimizar las búsquedas en el AST, Ruby MRI mantiene una caché de las variables locales. Es decir, utilizar variables locales será más rápido:
@var = "local variable, which is cached by Ruby, and requires a single lookup"
self.var = "requires walking the AST, and results in multiple lookups"
Mejor la interpolación que la concatenación
puts "This string embeds #{var1} and #{var2} through interpolation" # faster
puts "This string concatenates " << var1 << " and " << var 2 # slower
Utilizar métodos destructivos
Cuando disponemos de un método no destructivo y su pareja destructiva, como gsub y gsub!, suele ser más eficiente utilizar el método destructivo. Los métodos no destructivos suelen ser más lentos ya que tienen que realizar copias de los objectos.
hash = {}
hash = hash.merge({1 => 2}) # duplicates the original hash
hash.merge!({1 => 2}) # equivalent to previous line, and faster
Utilizar bloques en lugar de Symbol.to_proc
@widget_ids = @widgets.map(&:id) # Symbol.to_proc method, order of magniture slower...
@widget_ids = @widgets.collect {|w| w.id } # faster and simpler
Compruebalo tú mismo
Si tienes dudas sobré qué código será más rápido, es sencillo comprobarlo:
require 'benchmark'
n = 100000
Benchmark.bm do |x|
x.report('copy') { n.times do ; h = {}; h = h.merge({1 => 2}); end }
x.report('no copy') { n.times do ; h = {}; h.merge!({1 => 2}); end }
end
copy 0.350000 0.060000 0.410000 ( 0.419445)
no copy 0.250000 0.020000 0.270000 ( 0.276030)
5 de Julio de 2008
ruby, rails
Si utilizamos subversion como software de control de versiones, cada vez que creemos un nuevo proyecto rails, habrá una serie de tareas que tendremos que llevar a cabo.
Supongamos que el repositorio está creado y accesible en la URL:
http://svn.misite.com/miproyecto
Lo primero que tendremos que hacer, siguiendo las buenas prácticas del control de versiones con subversion, es crear tres carpetas: trunk, tags y branches.
$ REPO=http://svn.misite.com/miproyecto
$ svn mkdir --message="Layout inicial" $REPO/trunk $REPO/tags $REPO/branches
Commit de la revisión 1.
Después creamos la aplicación rails como siempre:
$ rails miproyecto
create
create app/controllers
create app/helpers
...
Ahora, en lugar de hacer un svn import, lo recomendable es hacer un svn checkout del trunk en el directorio de la aplicación y a continuación añadir la estructura de directorios del proyecto. De esta manera podemos eliminar algunos ficheros del control de versiones antes de hacer el commit:
$ cd miproyecto
$ svn checkout $REPO/trunk .
Revisión obtenida: 1
$ svn add --force .
A lib
A lib/tasks
...
Los ficheros de log no necesitaremos que estén bajo el control de versiones:
$ svn revert log/*
Se revirtió 'log/development.log'
Se revirtió 'log/production.log'
Se revirtió 'log/server.log'
Se revirtió 'log/test.log'
$ svn propset svn:ignore "*.log" log
propiedad 'svn:ignore' asignada en 'log'
De la misma manera, como cada desarrollador puede tener un database.yml diferente, será una buena idea eliminarlo del control de versiones:
$ svn revert config/database.yml
Se revirtió 'config/database.yml'
$ mv config/database.yml config/database.yml.sample
$ svn add config/database.yml.sample
A config/database.yml.sample
$ svn propset svn:ignore "database.yml" config
propiedad 'svn:ignore' asignada en 'config'
$ cp config/database.yml.sample config/database.yml
Asimismo, el fichero schema.rb, al ser generado dinámicamente por las migraciones, no tiene sentido tampoco que esté bajo el control de versiones:
$ svn propset svn:ignore "schema.rb" db
propiedad 'svn:ignore' asignada en 'db'
También interesará eliminar del control de versiones cualquier fichero que se genere en tmp:
$ svn propset svn:ignore "*" tmp
propiedad 'svn:ignore' asignada en 'tmp'
Ahora ya podremos hacer nuestro primer commit al repositorio:
$ svn commit -m "Nueva aplicación"
Entradas relacionadas
1 de Julio de 2008
ruby, rails
Noticias destacadas de Ruby y Rails durante el mes de junio de 2008:
1 de Junio de 2008
ruby, rails
Noticias destacadas de Ruby y Rails durante el mes de mayo de 2008:
9 de Mayo de 2008
ruby, rails
Hace poco comentaba que Ruby es el octavo lenguaje de programación que más libros vende. En el ranking que elabora TIOBE sobre la popularidad de los lenguajes de programación, Ruby ha subido también al octavo puesto al noveno puesto.
En la gráfica puede observarse cómo los líderes siguen siendo Java y C, ambos lenguaje estáticos y ambos en clara tendencia bajista desde hace años. Visual Basic, PHP (se mantienen) y C++ (bajista) están prácticamente empatados. Perl, en sexto puesto, también es bajista desde hace unos tres años. Los lenguajes emergentes y en ascenso son Python, C#, Ruby y Delphi.
Visto en el blog de aspgems.