https://github.com/agrafix/rubyspeed
Compile ruby functions to C
https://github.com/agrafix/rubyspeed
c compiler performance ruby
Last synced: 9 months ago
JSON representation
Compile ruby functions to C
- Host: GitHub
- URL: https://github.com/agrafix/rubyspeed
- Owner: agrafix
- Created: 2020-09-14T06:04:24.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-09-21T01:24:05.000Z (over 5 years ago)
- Last Synced: 2025-03-08T20:48:57.947Z (10 months ago)
- Topics: c, compiler, performance, ruby
- Language: Ruby
- Homepage:
- Size: 57.6 KB
- Stars: 183
- Watchers: 11
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Rubyspeed
_Work in progress._
Welcome to Rubyspeed. Right now, Rubyspeed is a basic proof of concept (horribly hacked together) that allows annotating method declarations to automatically be specialized and compiled to C. Here's an example:
``` ruby
require 'rubyspeed'
class TestClass
extend(Rubyspeed::Compiles)
compile!(params: [Rubyspeed::T.array(Rubyspeed::T.int), Rubyspeed::T.array(Rubyspeed::T.int)], return_type: Rubyspeed::T.int)
def self.dot(a, b)
c = Rubyspeed::Let.int(0)
a.each_with_index do |a_val, idx|
c += a_val * b[idx]
end
c
end
end
```
This will automatically replace the `dot` implementation with a compiled C version, that runs quite a bit (5x) faster than the native ruby version:
```shellsession
$ rake bench
user system total real
compiled 0.000021 0.000004 0.000025 ( 0.000018)
ruby 0.000105 0.000002 0.000107 ( 0.000103)
```
## How does this work?
In short:
* Use a neat annotation trick inspired by the [sorbet runtime](https://github.com/sorbet/sorbet/blob/d4c80e0ac3b04e64770f1b050fbab3c6c39b58eb/gems/sorbet-runtime/lib/types/private/methods/_methods.rb#L461) to emulate annotations (compare to `@Deprecated` in Java for example)
* Extract the ruby source from the given method
* Transform it to s-expressions
* Generate C code from the s-expressions
* Use a C compiler to compile to a ruby module
* Replace original implementation with a call to the compiled ruby module
## Inspiration
This project was inspired by [Stephen Diehl's LLVM specializer for Python](http://dev.stephendiehl.com/numpile/) and [rubyinline](https://github.com/seattlerb/rubyinline).
## Current Status
The project can only compile extremely primitive functions (basically only simple numeric computations). I am open to any pull requests for improvements, but would discourage using this in production anywhere :-)
## Hacking
``` shellsession
$ bundle install
$ rake test # run the tests
$ rake bench # run the benchmarks
```