2009-07-12 8 views
5

Tengo una función que compara 2 cadenas char por char. Necesitaba que corriera mucho más rápido que en Ruby, así que usé RubyInline para reescribir la función en C. Aumentó la velocidad unas 100 veces. La función tiene este aspecto:Cómo convertir una matriz de rubíes en una matriz C con RubyInline?

require 'inline' 

    inline do |builder| 
    builder.c " 
     static int distance(char *s, char *t){ 
     ... 
     }" 
    end 

Sin embargo, necesito comparar cadenas de Unicode. Así que decidí usar un paquete ("U *") y comparar matrices de enteros en su lugar. No puedo descifrar, a partir de una escasa documentación sobre RubyInline, cómo pasar las matrices de ruby ​​en la función y cómo convertirlas en matrices en C. ¡Cualquier ayuda es apreciada!

+0

No hay problema, déjame saber cómo resulta. Me encantaría ver su implementación cuando haya terminado. –

+0

Este es el código de la distancia damerau_levenshtein: http://gist.github.com/147023 para Ruby 1.8.7 funciona como un encanto, pero se ahoga con ruby ​​1.9.1 – dimus

+0

I http actualización: // GIST. github.com/147023 para trabajar con 1.9.1 ruby ​​también con la ayuda de thnetos – dimus

Respuesta

9

Esto tiene un buen resumen de cómo acceder a los objetos de Ruby desde C: http://rubycentral.com/pickaxe/ext_ruby.html

inline do |builder| 
    builder.c " 
    static VALUE some_method(VALUE s) { 
     int s_len = RARRAY(s)->len; 
     int result = 0; 

     VALUE *s_arr = RARRAY(s)->ptr; 

     for(i = 0; i < s_len; i++) { 
     result += NUM2INT(s_arr[i]); // example of reference 
     } 

     return INT2NUM(result); // convert C int back into ruby Numeric 
    }" 
end 

Luego, en el rubí que sólo puede pasar valores a ella como:

object.some_method([1,2,3,4]) 

la esperanza que esto te ayuda .

+0

Gracias Corban, ¡se ve exactamente lo que necesito! – dimus

4

Teniendo en cuenta el código de la respuesta anterior, aquí está el código que va a trabajar para Ruby 1.8.6 y 1.9.1:

inline do |builder| 
    builder.c " 
    static VALUE some_method(VALUE s) { 
     int s_len = RARRAY_LEN(s); 
     int result = 0; 
     int i = 0; 

     VALUE *s_arr = RARRAY_PTR(s); 

     for(i = 0; i < s_len; i++) { 
     result += NUM2INT(s_arr[i]); // example of reference 
     } 

     return INT2NUM(result); // convert C int back into ruby Numeric 
    }" 
end 

Esperanza esto ayuda también :)

+0

Gracias thnetos, solucionó el problema, actualicé el ejemplo github gist – dimus

Cuestiones relacionadas