With the release of Go 1.5, it is possible to make a go library for third-party programs in other languages. That is, you can write a package that does something interesting and hard or just a ready-made solution and connect it to another non-Go program. This may be C, android, objective C and etc. I will show how it can be easily connected to Ruby.
1. If you have a ready-made solution for a go problem, then why not write it again in Ruby;
2. Go is obviously faster than Ruby if we are talking about our logic and not ready-made solutions with gem in which C often works;
3. Go requires less memory if you need to work with a bunch of data.
Let's start with the Go package.
We write our fast good working solutions on Go:
This should contain main. Be sure to specify:
import "C"
And for the function that will be available from the outside, you must specify:
Now that the GO program is ready, you need to build it:
go build -buildmode=c-shared -o libadd.so testruby.go
-buildmode is what appeared on Go 1.5, there are several different options, we need c-shared. After compilation we get .so and .h file. Now it can be switched to non-GO programs.
')
Now part of ruby.
We need gem
ffi . We install it via gem install or via gemfile + bundle install. We connect our library to Ruby:
Ruby Code require 'ffi' module MegaSum extend FFI::Library ffi_lib 'lib/libadd.so' attach_function :add, [:int, :int], :int end
Here we indicate where our .so file is, what call functions it has (on which we wrote "// export"), what they accept and what they return (you can see the full list of types
here ). After that you can work:
Call go def self.add_go(x,y) Sum.add(x,y) end
The first call will be a little slow (probably loads everything into memory).
Benchmarks!
Ruby code that does the same def self.add_ruby(x,y) c = 0 i = 0 while i<50000 c += x + y + 1 i = i+1 end c end
[21] pry(main)> Benchmark.realtime { (1..1000).to_a.each {GoHello.add_ruby(3,2) }} => 1.763254 [22] pry(main)> Benchmark.realtime { (1..1000).to_a.each {GoHello.add_go(3,2) }} => 0.030442 [23] pry(main)> Benchmark.realtime { (1..100000).to_a.each {GoHello.add_go(3,2) }} => 3.103797 [24] pry(main)> Benchmark.realtime { (1..100000).to_a.each {GoHello.add_ruby(3,2) }} => 195.282368
As you can see, in simple arithmetic, Go overtakes Ruby by 60 times.
Minuses:
1. I'm not sure that you can build a bunch of Gorutin in Go. It worked for me on a small check (not thousands of gorutin);
P.C .: There is a similar solution for Python
here .