Last active
June 2, 2018 08:28
-
-
Save frsyuki/1dc489476dd569a12b28e325214f5d30 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'mkmf' | |
have_header("ruby/st.h") | |
have_header("st.h") | |
$CFLAGS << %[ -Wall -O3 -g] | |
$CFLAGS << " " << `pkg-config --cflags luajit`.strip | |
$LDFLAGS << " " << `pkg-config --libs-only-L --libs-only-l luajit`.strip | |
create_makefile('message_query/message_query') | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ruby.h" | |
#include <lua.h> | |
#include <lualib.h> | |
#include <lauxlib.h> | |
#include "luajit.h" | |
struct query_t; | |
typedef struct query_t query_t; | |
struct query_t { | |
lua_State *lua; | |
VALUE filter_code; | |
VALUE map_code; | |
VALUE reduce_code; | |
}; | |
#define QUERY_T(from, name) \ | |
query_t* name; \ | |
Data_Get_Struct(from, query_t, name); \ | |
if(name == NULL) { \ | |
rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \ | |
} | |
static void Query_free(query_t* q) | |
{ | |
if(q == NULL) { | |
return; | |
} | |
xfree(q); | |
} | |
static void Query_init(query_t* q) | |
{ | |
q->lua = luaL_newstate(); | |
if (q->lua == NULL) { | |
rb_raise(rb_eRuntimeError, "Failed to allocate a new Lua state."); \ | |
} | |
luaL_openlibs(q->lua); | |
} | |
static void Query_mark(query_t* q) | |
{ | |
} | |
VALUE Query_initialize(VALUE self, VALUE path) | |
{ | |
QUERY_T(self, q); | |
Check_Type(path, T_STRING); | |
//char* path_str = malloc(RSTRING_LEN(path) + 1); | |
//memcpy(path_str, RSTRING_PTR(path), RSTRING_LEN(path)); | |
//path_str[RSTRING_LEN(path)] = '\0'; | |
//int ret = luaL_loadfile(q->lua, path_str); | |
//free(path_str); | |
int ret = luaL_loadfile(q->lua, RSTRING_PTR(path)); | |
if (ret != LUA_OK) { | |
rb_raise(rb_eRuntimeError, "Failed to compile Lua script."); \ | |
} | |
return self; | |
} | |
VALUE Query_alloc(VALUE klass) | |
{ | |
query_t* q = ZALLOC_N(query_t, 1); | |
Query_init(q); | |
VALUE self = Data_Wrap_Struct(klass, Query_mark, Query_free, q); | |
return self; | |
} | |
static VALUE Query_apply(VALUE self, VALUE data) | |
{ | |
QUERY_T(self, q); | |
Check_Type(data, T_STRING); | |
lua_pushlstring(q->lua, RSTRING_PTR(data), RSTRING_LEN(data)); | |
lua_setglobal(q->lua, "data"); | |
int ret = lua_pcall(q->lua, 0, 1, 0); | |
if (ret != LUA_OK) { | |
rb_raise(rb_eRuntimeError, "Failed to evaluate Lua script."); \ | |
} | |
size_t len; | |
const char* ptr = lua_tolstring(q->lua, -1, &len); | |
return rb_str_new(ptr, len); | |
} | |
void Init_message_query(void) | |
{ | |
VALUE cQuery = rb_define_class("MessageQuery", rb_cObject); | |
cQuery = rb_define_class_under(cQuery, "Query", rb_cObject); | |
rb_define_alloc_func(cQuery, Query_alloc); | |
rb_define_method(cQuery, "initialize", Query_initialize, 1); | |
rb_define_method(cQuery, "apply", Query_apply, 1); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source 'https://rubygems.org/' | |
gemspec | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Gem::Specification.new do |s| | |
s.name = "message_query" | |
s.version = "0.1.0" | |
s.summary = "MessagePack Query" | |
s.description = %q{MessagePack Query} | |
s.authors = ["Sadayuki Furuhashi"] | |
s.email = ["[email protected]"] | |
s.license = "Apache 2.0" | |
s.homepage = "http://msgpack.org/" | |
s.has_rdoc = false | |
s.require_paths = ["lib"] | |
s.files = `git ls-files`.split("\n") | |
s.extensions = ["ext/message_query/extconf.rb"] | |
s.test_files = `git ls-files -- {test,spec}/*`.split("\n") | |
s.add_development_dependency 'bundler', ['~> 1.0'] | |
s.add_development_dependency 'rake' | |
s.add_development_dependency 'rake-compiler', ['~> 1.0'] | |
s.add_development_dependency 'rspec', ['~> 3.3'] | |
s.add_development_dependency 'json' | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# $ ruby -Ilib -Iext ex.rb data.msgpack | |
# Rehearsal ------------------------------------------------------- | |
# MessageQuery LuaJIT 1.190000 0.000000 1.190000 ( 1.189161) | |
# Ruby 2.5.1 1.360000 0.000000 1.360000 ( 1.365458) | |
# ---------------------------------------------- total: 2.550000sec | |
# | |
# user system total real | |
# MessageQuery LuaJIT 1.200000 0.000000 1.200000 ( 1.217826) | |
# Ruby 2.5.1 1.390000 0.000000 1.390000 ( 1.393994) | |
# {:lua=>837500, :ruby=>837500} | |
require 'message_query' | |
require 'msgpack' | |
require 'benchmark' | |
data = File.read(ARGV[0]) | |
filter_lua = %{not(string.sub(v[6], 1, 20) == "Mozilla/5.0 (Windows")} | |
map_lua = %{1} | |
reduce_lua = %{s = s + v} | |
mq = MessageQuery.new(filter_lua, map_lua, reduce_lua) | |
r = {} | |
Benchmark.bmbm do |x| | |
x.report("MessageQuery LuaJIT") do | |
r[:lua] = mq.apply(data, 0) | |
end | |
x.report("Ruby #{RUBY_VERSION}") do | |
state = 0 | |
MessagePack::Unpacker.new.feed_each(data) do |v| | |
if v[5][0, 20] != "Mozilla/5.0 (Windows" | |
state += 1 | |
end | |
end | |
r[:ruby] = state | |
end | |
end | |
p r | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'bundler' | |
Bundler::GemHelper.install_tasks | |
spec = eval File.read("message_query.gemspec") | |
require 'rake/extensiontask' | |
Rake::ExtensionTask.new('message_query', spec) do |ext| | |
ext.ext_dir = 'ext/message_query' | |
ext.cross_compile = true | |
ext.lib_dir = File.join(*['lib', 'message_query', ENV['FAT_DIR']].compact) | |
# cross_platform names are of MRI's platform name | |
ext.cross_platform = ['x86-mingw32', 'x64-mingw32'] | |
end | |
CLEAN.include('lib/message_query/message_query.*') | |
task :default => [:build] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment