Inside Out Ruby: Using MRI as a C library - Artur Pyrogovskyi

Ruby Meditation
Ruby MeditationRuby Meditation
Вівторок, 19 березня 13 р.
Inside-Out Ruby: Using
MRI as a C library
Вівторок, 19 березня 13 р.
About me
Arthur Pirogovski
arthur@flyintealeaf.com
Вівторок, 19 березня 13 р.
About me
Coding for , mostly Ruby.
Вівторок, 19 березня 13 р.
About me
And C.
segfault(87698) malloc: *** error for object
0x7fff5dbad6c0:
pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Вівторок, 19 березня 13 р.
About Ruby
Вівторок, 19 березня 13 р.
About Ruby
very readable
Вівторок, 19 березня 13 р.
About Ruby
“#{@str[:mostly]}”
very readable
Вівторок, 19 березня 13 р.
About Ruby
very bad concurrency.
Вівторок, 19 березня 13 р.
About Ruby
Mediocre speed
Вівторок, 19 березня 13 р.
About C
Вівторок, 19 березня 13 р.
About C
very unreadable
void (*signal(int, void (*fp)(int)))(int);
Вівторок, 19 березня 13 р.
About C
concurrency is as good
as your programming skills are
Вівторок, 19 березня 13 р.
About C
conc is urrencyaods go
amings your program ls askilre
Вівторок, 19 березня 13 р.
About C
only FORTRAN is faster
Вівторок, 19 березня 13 р.
About C
Actually, not
Вівторок, 19 березня 13 р.
Native Extensions
Вівторок, 19 березня 13 р.
Native Extensions
• great speedup
•
•
Вівторок, 19 березня 13 р.
Native Extensions
• great speedup
• portability problems #ifdef
•
Вівторок, 19 березня 13 р.
Native Extensions
• great speedup
• portability problems #ifdef
• secret concurrency (don’t tell Ruby)
Вівторок, 19 березня 13 р.
What if we turn it
inside out?
Вівторок, 19 березня 13 р.
Strings
“much”*10 easier in Ruby
than in char ** C
Вівторок, 19 березня 13 р.
DSL
Turing-complete out of the box
Вівторок, 19 березня 13 р.
DSL
Turing-complete out of the box
Pretty like drugs
Вівторок, 19 березня 13 р.
Calling Ruby code
- Hey, I’m C!
(awkward silence)
- Hey, I’m Ruby!
Вівторок, 19 березня 13 р.
Garbage Collector
Very bad one, but still better than none
Вівторок, 19 березня 13 р.
Well-known APIs
VALUE hash = rb_hash_new();
VALUE key = rb_string_new2(“key”);
VALUE value = INT2FIX(42);
rb_hash_aset(hash, key, value);
rb_p(hash);
Вівторок, 19 березня 13 р.
MVP
#ifdef __APPLE__
#define HAVE_STRUCT_TIMESPEC 1
#endif
Вівторок, 19 березня 13 р.
MVP
#ifdef __APPLE__
#define HAVE_STRUCT_TIMESPEC 1
#endif
#include <ruby.h>
Вівторок, 19 березня 13 р.
MVP
#ifdef __APPLE__
#define HAVE_STRUCT_TIMESPEC 1
#endif
#include <ruby.h>
int main() {
ruby_init();
return 0;
}
Вівторок, 19 березня 13 р.
MVP
#ifdef __APPLE__
#define HAVE_STRUCT_TIMESPEC 1
#endif
#include <ruby.h>
int main() {
ruby_init();
ruby_init_loadpath();
return 0;
}
Вівторок, 19 березня 13 р.
MVP
#ifdef __APPLE__
#define HAVE_STRUCT_TIMESPEC 1
#endif
#include <ruby.h>
int main() {
ruby_init();
ruby_init_loadpath();
ruby_script("c.rb");
return 0;
}
Вівторок, 19 березня 13 р.
MVP
#ifdef __APPLE__
#define HAVE_STRUCT_TIMESPEC 1
#endif
#include <ruby.h>
int main() {
ruby_init();
ruby_init_loadpath();
ruby_script("c.rb");
ruby_finalize();
return 0;
}
Вівторок, 19 березня 13 р.
MVP
#ifdef __APPLE__
#define HAVE_STRUCT_TIMESPEC 1
#endif
#include <ruby.h>
int main() {
ruby_init();
ruby_init_loadpath();
ruby_script("c.rb");
VALUE ruby_string = rb_str_new2("Hi,I’m Ruby!");
rb_p(ruby_string);
ruby_finalize();
return 0;
}
Вівторок, 19 березня 13 р.
MVP
$ gcc minimal_embedded_ruby.c 
-o meruby -lruby 
-I ${MY_RUBY_HOME}/include/ruby-1.9.1
-I ${MY_RUBY_HOME}/include/
ruby-1.9.1/x86_64-linux 
-L $MY_RUBY_HOME/lib
$ ./meruby
"Hi from Ruby!"
Note: $MY_RUBY_HOME is RVM-specific
Вівторок, 19 березня 13 р.
Warning #1
Ruby can only be initialized
from the main thread
Вівторок, 19 березня 13 р.
Warning #2
DO NOT call ruby_run()
It intercepts control flow and never returns.
Вівторок, 19 березня 13 р.
Memory
management
Вівторок, 19 березня 13 р.
Memory
management
not fun.
Вівторок, 19 березня 13 р.
This will SEGFAULT
int main() {
ruby_init();
ruby_init_loadpath();
ruby_script("c.rb");
VALUE ruby_string = rb_str_new2("Hi,I’m
Ruby!");
rb_p(ruby_string);
rb_gc();
rb_p(ruby_string); /* Right here */
ruby_finalize();
return 0;
}
Вівторок, 19 березня 13 р.
Registering vars
#include <ruby.h>
static VALUE ruby_objects;
void lo(VALUE ruby_object) {
rb_hash_aset(ruby_objects,
rb_obj_id(ruby_object),
ruby_object);
}
void uo(VALUE ruby_object) {
rb_hash_delete(ruby_objects,
rb_obj_id(ruby_object));
}
Вівторок, 19 березня 13 р.
Registering vars
int main() {
ruby_init();
...
ruby_objects = rb_hash_new();
rb_global_variable(&ruby_objects);
}
Вівторок, 19 березня 13 р.
Registering vars
int main() {
ruby_init();
...
ruby_objects = rb_hash_new();
rb_global_variable(&ruby_objects);
VALUE ruby_string = rb_str_new2("Hi
from Ruby!");
}
Вівторок, 19 березня 13 р.
Registering vars
int main() {
ruby_init();
...
ruby_objects = rb_hash_new();
rb_global_variable(&ruby_objects);
VALUE ruby_string = rb_str_new2("Hi from
Ruby!");
lo(ruby_string);
rb_p(ruby_string);
rb_gc();
}
Вівторок, 19 березня 13 р.
Registering vars
int main() {
ruby_init();
...
ruby_objects = rb_hash_new();
rb_global_variable(&ruby_objects);
VALUE ruby_string = rb_str_new2("Hi from Ruby!");
lo(ruby_string);
rb_p(ruby_string);
rb_gc();
rb_p(ruby_string); /* No SEGFAULT this time */
uo(ruby_string);
...
}
Вівторок, 19 березня 13 р.
GC tips
call rb_gc() to collect
can also be invoked by Ruby itself
Вівторок, 19 березня 13 р.
GC tips
always register variables
rb_gc_register_address() is slow,
so use some data structure
Вівторок, 19 березня 13 р.
GC tips
run rb_gc() often to detect problems early
automatic GC can be disabled (dangerous!)
Вівторок, 19 березня 13 р.
Exceptions
Вівторок, 19 березня 13 р.
Exceptions
are evil.
Вівторок, 19 березня 13 р.
Exceptions
rb_raise()
rb_rescue()
rb_ensure()
Вівторок, 19 березня 13 р.
Exceptions
rb_raise() is a longjmp()
longjmp() skips your free()’s
Вівторок, 19 березня 13 р.
Exceptions
rb_protect() is a good catch-all wrapper
Вівторок, 19 березня 13 р.
Exceptions
int state = 0;
rb_protect(
RUBY_METHOD_FUNC(rb_require),
(VALUE) “./code.rb”,
&state);
/* We couldn't execute rb_require */
if (state) {
rb_p(rb_gv_get("$!"));
exit(1);
}
Вівторок, 19 березня 13 р.
Functions:
calling from C
VALUE new_object =
rb_funcall(some_class,
rb_intern("new"), 1, arg1);
Вівторок, 19 березня 13 р.
Functions:
exporting to Ruby
rb_define_singleton_method(
some_class, “method_name”,
method_name_in_c, -1)
Вівторок, 19 березня 13 р.
Functions:
exporting to Ruby
static VALUE
method_name_in_c(int argc,
VALUE * argv, VALUE self)
Вівторок, 19 березня 13 р.
Functions:
exporting to Ruby
rb_scan_args(argc, argv,
“11”, &arg1, &arg2);
Вівторок, 19 березня 13 р.
Speed
For simple tasks,
C-based loader is up to 4x faster
Вівторок, 19 березня 13 р.
Speed
But for complex tasks,
speed gain is only about 15%
Вівторок, 19 березня 13 р.
Speed
Pure C code is up to 15x times faster
Вівторок, 19 березня 13 р.
Docs
README.EXT
Vim’s if_ruby.c
Ruby source code
Вівторок, 19 березня 13 р.
Examples
https://github.com/arp/ruby_from_c
Вівторок, 19 березня 13 р.
Thanks
Questions?
Вівторок, 19 березня 13 р.
Bonus
FastCGI + Ruby + C
Вівторок, 19 березня 13 р.
1 of 65

Recommended

Is this Legacy or Revenant Code? - Sergey Sergyenko | Ruby Meditation 30 by
Is this Legacy or Revenant Code? - Sergey Sergyenko  | Ruby Meditation 30Is this Legacy or Revenant Code? - Sergey Sergyenko  | Ruby Meditation 30
Is this Legacy or Revenant Code? - Sergey Sergyenko | Ruby Meditation 30Ruby Meditation
207 views22 slides
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky... by
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...
Life with GraphQL API: good practices and unresolved issues - Roman Dubrovsky...Ruby Meditation
462 views141 slides
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29 by
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29
Where is your license, dude? - Viacheslav Miroshnychenko | Ruby Meditation 29Ruby Meditation
210 views49 slides
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ... by
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...
Dry-validation update. Dry-validation vs Dry-schema 1.0 - Aleksandra Stolyar ...Ruby Meditation
1.6K views59 slides
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28 by
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28 How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28
How to cook Rabbit on Production - Bohdan Parshentsev | Ruby Meditation 28 Ruby Meditation
366 views23 slides
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28 by
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28
How to cook Rabbit on Production - Serhiy Nazarov | Ruby Meditation 28Ruby Meditation
459 views20 slides

More Related Content

More from Ruby Meditation

Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio... by
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...Ruby Meditation
320 views80 slides
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or... by
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...Ruby Meditation
285 views49 slides
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27 by
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27Ruby Meditation
1.1K views96 slides
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26 by
New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26Ruby Meditation
577 views56 slides
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26 by
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26Ruby Meditation
299 views51 slides
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (... by
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...Ruby Meditation
455 views78 slides

More from Ruby Meditation(20)

Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio... by Ruby Meditation
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Use cases for Serverless Technologies - Ruslan Tolstov (RUS) | Ruby Meditatio...
Ruby Meditation320 views
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or... by Ruby Meditation
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
The Trailblazer Ride from the If Jungle into a Civilised Railway Station - Or...
Ruby Meditation285 views
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27 by Ruby Meditation
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
What/How to do with GraphQL? - Valentyn Ostakh (ENG) | Ruby Meditation 27
Ruby Meditation1.1K views
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26 by Ruby Meditation
New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26New features in Rails 6 -  Nihad Abbasov (RUS) | Ruby Meditation 26
New features in Rails 6 - Nihad Abbasov (RUS) | Ruby Meditation 26
Ruby Meditation577 views
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26 by Ruby Meditation
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Security Scanning Overview - Tetiana Chupryna (RUS) | Ruby Meditation 26
Ruby Meditation299 views
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (... by Ruby Meditation
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Teach your application eloquence. Logs, metrics, traces - Dmytro Shapovalov (...
Ruby Meditation455 views
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26 by Ruby Meditation
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26
Best practices. Exploring - Ike Kurghinyan (RUS) | Ruby Meditation 26
Ruby Meditation204 views
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25 by Ruby Meditation
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25
Road to A/B testing - Alexey Vasiliev (ENG) | Ruby Meditation 25
Ruby Meditation577 views
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita... by Ruby Meditation
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...
Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Medita...
Ruby Meditation511 views
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me... by Ruby Meditation
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...
Data encryption for Ruby web applications - Dmytro Shapovalov (RUS) | Ruby Me...
Ruby Meditation299 views
Rails App performance at the limit - Bogdan Gusiev by Ruby Meditation
Rails App performance at the limit - Bogdan GusievRails App performance at the limit - Bogdan Gusiev
Rails App performance at the limit - Bogdan Gusiev
Ruby Meditation418 views
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23 by Ruby Meditation
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23
GDPR. Next Y2K in 2018? - Anton Tkachov | Ruby Meditation #23
Ruby Meditation179 views
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton... by Ruby Meditation
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...
Postgres vs Elasticsearch while enriching data - Vlad Somov | Ruby Meditaiton...
Ruby Meditation2.7K views
Database Sharding in Rails Applications – Vitalik Danchenko | Ruby Meditatio... by Ruby Meditation
 Database Sharding in Rails Applications – Vitalik Danchenko | Ruby Meditatio... Database Sharding in Rails Applications – Vitalik Danchenko | Ruby Meditatio...
Database Sharding in Rails Applications – Vitalik Danchenko | Ruby Meditatio...
Ruby Meditation824 views
Building MVP from business owner’s perspective – Piotr Latoszek | Ruby Medita... by Ruby Meditation
Building MVP from business owner’s perspective – Piotr Latoszek | Ruby Medita...Building MVP from business owner’s perspective – Piotr Latoszek | Ruby Medita...
Building MVP from business owner’s perspective – Piotr Latoszek | Ruby Medita...
Ruby Meditation340 views
Growing Rails Apps - Dmitry Zhlobo | Ruby Meditation #23 by Ruby Meditation
Growing Rails Apps - Dmitry Zhlobo | Ruby Meditation #23Growing Rails Apps - Dmitry Zhlobo | Ruby Meditation #23
Growing Rails Apps - Dmitry Zhlobo | Ruby Meditation #23
Ruby Meditation202 views
Residence permit EU - Gennadii Miroshnychenko by Ruby Meditation
Residence permit EU - Gennadii MiroshnychenkoResidence permit EU - Gennadii Miroshnychenko
Residence permit EU - Gennadii Miroshnychenko
Ruby Meditation157 views
Practical SOLID with Rails - Andrii Savchenko by Ruby Meditation
Practical SOLID with Rails - Andrii SavchenkoPractical SOLID with Rails - Andrii Savchenko
Practical SOLID with Rails - Andrii Savchenko
Ruby Meditation140 views
Getting new devs up to speed - Ivan Zarea by Ruby Meditation
Getting new devs up to speed - Ivan ZareaGetting new devs up to speed - Ivan Zarea
Getting new devs up to speed - Ivan Zarea
Ruby Meditation105 views

Inside Out Ruby: Using MRI as a C library - Artur Pyrogovskyi