Как преобразовать массив ruby ​​в массив C с RubyInline? - PullRequest
5 голосов
/ 13 июля 2009

У меня есть функция, которая сравнивает 2 строки char на char. Мне нужно, чтобы он работал намного быстрее, чем в Ruby, поэтому я использовал RubyInline, чтобы переписать функцию в C. Это действительно увеличило скорость примерно в 100 раз. Функция выглядит так:

  require 'inline'

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

Однако мне нужно сравнить строки Unicode. Поэтому я решил использовать unpack ("U *") и сравнивать массивы целых чисел. Я не могу понять из скудной документации для RubyInline, как передать массивы ruby ​​в функцию и как преобразовать их в массивы C. Любая помощь приветствуется!

Ответы [ 2 ]

9 голосов
/ 13 июля 2009

Это краткое изложение того, как получить доступ к объектам Ruby из 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

Тогда в ruby ​​вы можете просто передать ему значения вроде:

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

Надеюсь, это поможет вам.

4 голосов
/ 15 июля 2009

Учитывая код из приведенного выше ответа, вот код, который будет работать для Ruby 1.8.6 и 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

Надеюсь, это также поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...