Как вы используете язык C для создания рубинового камня? - PullRequest
12 голосов
/ 16 мая 2010

Я хотел бы увидеть некоторый исходный код или, возможно, ссылку на него, который дает хотя бы заглушку для написания рубиновых гемов на языках Си (C ++ ?? это тоже возможно?)

Кроме того, некоторые из вас могут знать, что Facebook изначально компилирует свой код в виде расширений php для повышения производительности. Кто-нибудь делает это в Rails? Если да, какой у вас был опыт с этим? Вы нашли это полезным?

Спасибо.

Edit: Я думаю, что я отвечу на свой собственный вопрос с некоторыми вещами, которые я узнал сегодня, но я собираюсь оставить вопрос открытым для другого ответа, потому что я хотел бы увидеть, что другие скажут по этой теме

1 Ответ

17 голосов
/ 18 мая 2010

Хорошо, поэтому я сел своему приятелю, с которым у меня все в порядке. Я показывал ему Руби, и он копал его. Когда мы встретились вчера вечером, я сказал ему, что вы можете написать камни Ruby на Си, что его заинтриговало. Вот что мы нашли:

Уроки / Примеры

http://www.eqqon.com/index.php/Ruby_C_Extension

http://drnicwilliams.com/2008/04/01/writing-c-extensions-in-rubygems/

http://www.rubyinside.com/how-to-create-a-ruby-extension-in-c-in-under-5-minutes-100.html

ruby-doc (исходный код ruby.h)

http://ruby -doc.org / Doxygen / 1.8.4 / ruby_8h-source.html

Вот некоторый исходный код, который мы также написали, чтобы проверить его:

Открыть терминал:

prompt>mkdir MyTest
prompt>cd MyTest
prompt>gedit extconf.rb

Затем вы помещаете этот код в extconf.rb

# Loads mkmf which is used to make makefiles for Ruby extensions
require 'mkmf'

# Give it a name
extension_name = 'mytest'

# The destination
dir_config(extension_name)

# Do the work
create_makefile(extension_name)

Сохраните файл, затем напишите MyTest.c

#include "ruby.h"

// Defining a space for information and references about the module to be stored internally
VALUE MyTest = Qnil;

// Prototype for the initialization method - Ruby calls this, not you
void Init_mytest();

// Prototype for our method 'test1' - methods are prefixed by 'method_' here
VALUE method_test1(VALUE self);
VALUE method_add(VALUE, VALUE, VALUE);

// The initialization method for this module
void Init_mytest() {
MyTest = rb_define_module("MyTest");
rb_define_method(MyTest, "test1", method_test1, 0);
rb_define_method(MyTest, "add", method_add, 2);
}

// Our 'test1' method.. it simply returns a value of '10' for now.
VALUE method_test1(VALUE self) {
int x = 10;
return INT2NUM(x);
}

// This is the method we added to test out passing parameters
VALUE method_add(VALUE self, VALUE first, VALUE second) {
int a = NUM2INT(first);
int b = NUM2INT(second);
return INT2NUM(a + b);
}

Из приглашения вам нужно создать Makefile, запустив extconf.rb:

prompt>ruby extconf.rb
prompt>make
prompt>make install

Вы можете проверить это:

prompt>irb
irb>require 'mytest'
irb>include MyTest
irb>add 3, 4 # => 7

Мы провели бенчмарк-тест, и ruby ​​добавили 3 и 4 вместе 10 миллионов раз, а затем 10 миллионов раз также позвонили нашему расширению C. В результате с использованием только ruby ​​для выполнения этой задачи потребовалось 12 секунд, а с использованием расширения C - всего 6 секунд! Также обратите внимание, что большая часть этой обработки передает работу C для выполнения задачи. В одном из этих учебных пособий автор использовал рекурсию (последовательность Фибоначчи) и сообщил, что расширение C прошло в 51 раз быстрее!

...