Skip to content

Instantly share code, notes, and snippets.

@mattn
Last active January 2, 2016 11:39
Show Gist options
  • Save mattn/8297632 to your computer and use it in GitHub Desktop.
Save mattn/8297632 to your computer and use it in GitHub Desktop.
mruby method cacheパッチ
def fib n
return n if n < 2
fib(n-2) + fib(n-1)
end
puts fib(39)
diff --git a/include/mrbconf.h b/include/mrbconf.h
index bcef1b1..b31988e 100644
--- a/include/mrbconf.h
+++ b/include/mrbconf.h
@@ -59,6 +59,9 @@
/* fixed size GC arena */
//#define MRB_GC_FIXED_ARENA
+/* method cache */
+//#define MRB_METHOD_CACHE
+
/* -DDISABLE_XXXX to drop following features */
//#define DISABLE_STDIO /* use of stdio */
diff --git a/include/mruby.h b/include/mruby.h
index e925502..ddd88d7 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -96,6 +96,19 @@ enum gc_state {
GC_STATE_SWEEP
};
+#ifdef MRB_METHOD_CACHE
+#define MRB_CACHE_SIZE 0x800
+#define MRB_CACHE_MASK 0x7ff
+#define MRB_CACHE(c,m) ((((((unsigned long)(void*)c))>>3)^(m))&MRB_CACHE_MASK)
+
+/* method hash table. */
+struct mrb_cache_entry {
+ mrb_sym mid;
+ struct RClass *c;
+ struct RProc* p;
+};
+#endif
+
typedef struct mrb_state {
void *jmp;
@@ -162,6 +175,10 @@ typedef struct mrb_state {
struct RClass *eStandardError_class;
void *ud; /* auxiliary data */
+
+#ifdef MRB_METHOD_CACHE
+ struct mrb_cache_entry cache[MRB_CACHE_SIZE];
+#endif
} mrb_state;
typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value);
diff --git a/src/class.c b/src/class.c
index d290892..c35e4f1 100644
--- a/src/class.c
+++ b/src/class.c
@@ -991,6 +991,14 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
struct RProc *m;
struct RClass *c = *cp;
+#ifdef MRB_METHOD_CACHE
+ struct mrb_cache_entry* ce;
+ ce = mrb->cache + MRB_CACHE(c, mid);
+ if (ce->c == c && ce->mid == mid) {
+ return ce->p;
+ }
+#endif
+
while (c) {
khash_t(mt) *h = c->mt;
@@ -999,6 +1007,11 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
if (k != kh_end(h)) {
m = kh_value(h, k);
if (!m) break;
+#ifdef MRB_METHOD_CACHE
+ ce->mid = mid;
+ ce->c = *cp;
+ ce->p = m;
+#endif
*cp = c;
return m;
}
  • cruby (ruby 2.0.0p0 (2013-02-24) [i386-mingw32])

      c:\dev\mruby>w32time ruby fib.rb
      63245986
      real    10.428
      system  0.046
      user    10.374
    
  • mruby (メソッドキャッシュなし)

      c:\dev\mruby>w32time bin\mruby fib.rb
      63245986
      real    32.210
      system  0.000
      user    32.136
    
  • mruby (メソッドキャッシュあり)

      c:\dev\mruby>w32time bin\mruby fib.rb
      63245986
      real    30.622
      system  0.000
      user    30.607
    
  • メソッドキャッシュなし

      c:\dev\mruby>w32time bin\mruby.exe fib.rb
      63245986
      real    35.066
      system  0.000
      user    34.133
    
  • メソッドキャッシュあり

      c:\dev\mruby>w32time bin\mruby.exe fib.rb
      63245986
      real    31.444
      system  0.000
      user    31.215
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment