[#237] object.c ruby.h (fwd) — Robert Skarwecki <skaav@...>

Hello everybody,

42 messages 2002/07/24
[#239] Re: [PATCH] object.c ruby.h (fwd) — GOTO Kentaro <gotoken@...> 2002/07/24

At Thu, 25 Jul 2002 00:02:28 +0900,

[#240] Re: [PATCH] object.c ruby.h (fwd) — Dave Thomas <Dave@...> 2002/07/24

GOTO Kentaro <gotoken@notwork.org> writes:

[#246] Re: [PATCH] object.c ruby.h (fwd) — GOTO Kentaro <gotoken@...> 2002/07/25

At Thu, 25 Jul 2002 05:05:46 +0900,

[#247] Re: [PATCH] object.c ruby.h (fwd) — Dave Thomas <Dave@...> 2002/07/25

GOTO Kentaro <gotoken@notwork.org> writes:

[#248] Re: [PATCH] object.c ruby.h (fwd) — nobu.nokada@... 2002/07/25

Hi,

[#249] Re: [PATCH] object.c ruby.h (fwd) — Dave Thomas <Dave@...> 2002/07/25

nobu.nokada@softhome.net writes:

[#250] Re: [PATCH] object.c ruby.h (fwd) — nobu.nokada@... 2002/07/25

Hi,

[#252] Re: [PATCH] object.c ruby.h (fwd) — GOTO Kentaro <gotoken@...> 2002/07/25

At Fri, 26 Jul 2002 03:11:02 +0900,

[#253] Re: [PATCH] object.c ruby.h (fwd) — Dave Thomas <Dave@...> 2002/07/25

GOTO Kentaro <gotoken@notwork.org> writes:

speed improvements during ruby_init

From: Jamie Herre <jfh@...>
Date: 2002-07-14 00:39:32 UTC
List: ruby-core #227
Hi,

Messing around with gprof after being agitated by a recent thread 
regarding ruby IO, I found that the init phase is taking longer than 
necessary due to the following:

1) rb_clear_cache_by_id( ) is called many times during ruby init and 
parsing.  each call entails 0x800 comparisons. Proposed solution is to 
disable the method cache until ruby_run( ).

2) Although it may be necessary to rb_gc( ) after load_file( ), it is 
not always so for small scripts.  Proposed solution is to trigger gc 
based on malloc_memories.

These two changes can make short scripts run noticeably faster:

$ time ../ruby172/ruby hello_world.rb > /dev/null
real    0m0.028s
user    0m0.023s
sys     0m0.000s
$ time ../ruby_dev/ruby hello_world.rb  > /dev/null
real    0m0.011s
user    0m0.008s
sys     0m0.000s

$ time ../ruby172/ruby lib/cgi.rb
real    0m0.061s
user    0m0.055s
sys     0m0.000s
$ time ../ruby_dev/ruby lib/cgi.rb
real    0m0.034s
user    0m0.031s
sys     0m0.000s

-J

Would anyone care to check this?  Is this adding extraneous overhead to 
the method cache?

Jamie Herre
Gettys Group Software, Inc.



Index: eval.c
===================================================================
RCS file: /src/ruby/eval.c,v
retrieving revision 1.303
diff -u -r1.303 eval.c
--- eval.c	2002/06/24 07:20:42	1.303
+++ eval.c	2002/07/14 00:10:18
@@ -189,6 +189,8 @@
  };

  static struct cache_entry cache[CACHE_SIZE];
+static int cache_enabled = 0;
+/* must call rb_clear_cache when set cache_enabled = 1 */

  void
  rb_clear_cache()
@@ -246,7 +248,7 @@
  	rb_raise(rb_eSecurityError, "Insecure: can't define method");
      }
      if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
-    rb_clear_cache_by_id(mid);
+    if (cache_enabled) rb_clear_cache_by_id(mid);
      body = NEW_METHOD(node, noex);
      st_insert(RCLASS(klass)->m_tbl, mid, body);
  }
@@ -280,6 +282,7 @@
      NODE * volatile body;
      struct cache_entry *ent;

+    /* purposely ignoring cache_enabled here for simplicity */
      if ((body = search_method(klass, id, &origin)) == 0 || 
!body->nd_body) {
  	/* store empty info in cache */
  	ent = cache + EXPR1(klass, id);
@@ -333,7 +336,7 @@
  	rb_name_error(mid, "method `%s' not defined in %s",
  		      rb_id2name(mid), rb_class2name(klass));
      }
-    rb_clear_cache_by_id(mid);
+    if (cache_enabled) rb_clear_cache_by_id(mid);
      if (FL_TEST(klass, FL_SINGLETON)) {
  	rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1, 
ID2SYM(mid));
      }
@@ -440,7 +443,7 @@

      /* is it in the method cache? */
      ent = cache + EXPR1(klass, id);
-    if (ent->mid == id && ent->klass == klass) {
+    if (ent->mid == id && ent->klass == klass && cache_enabled) {
  	if (ex && (ent->noex & NOEX_PRIVATE))
  	    return Qfalse;
  	if (!ent->method) return Qfalse;
@@ -1228,6 +1231,10 @@

      if (ruby_nerrs > 0) exit(ruby_nerrs);

+    /* enable method caching */
+    rb_clear_cache();
+    cache_enabled = 1;
+
      Init_stack((void*)&tmp);
      PUSH_TAG(PROT_NONE);
      PUSH_ITER(ITER_NOT);
@@ -1684,7 +1691,7 @@
  	body = body->nd_head;
      }

-    rb_clear_cache_by_id(name);
+    if (cache_enabled) rb_clear_cache_by_id(name);
      st_insert(RCLASS(klass)->m_tbl, name,
  	      NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex));
      if (FL_TEST(klass, FL_SINGLETON)) {
@@ -4698,7 +4705,7 @@
      }
      /* is it in the method cache? */
      ent = cache + EXPR1(klass, mid);
-    if (ent->mid == mid && ent->klass == klass) {
+    if (ent->mid == mid && ent->klass == klass && cache_enabled) {
  	if (!ent->method)
  	    return rb_undefined(recv, mid, argc, argv, 
scope==2?CSTAT_VCALL:0);
  	klass = ent->origin;
@@ -5650,7 +5657,7 @@
      for (i=0; i<argc; i++) {
  	rb_export_method(self, rb_to_id(argv[i]), ex);
      }
-    rb_clear_cache_by_class(self);
+    if (cache_enabled) rb_clear_cache_by_class(self);
  }

  static VALUE
Index: gc.c
===================================================================
RCS file: /src/ruby/gc.c,v
retrieving revision 1.94
diff -u -r1.94 gc.c
--- gc.c	2002/05/14 06:22:26	1.94
+++ gc.c	2002/07/14 00:10:19
@@ -1199,6 +1199,13 @@
      gc_sweep();
  }

+void
+rb_gc_ifneeded()
+{
+  /* This is just an arbitrary guess for the value to cause a real gc */
+  if (malloc_memories > (GC_MALLOC_LIMIT/2)) rb_gc();
+}
+
  VALUE
  rb_gc_start()
  {
Index: ruby.c
===================================================================
RCS file: /src/ruby/ruby.c,v
retrieving revision 1.62
diff -u -r1.62 ruby.c
--- ruby.c	2002/05/29 05:20:33	1.62
+++ ruby.c	2002/07/14 00:10:20
@@ -854,7 +854,7 @@
      else if (f != rb_stdin) {
  	rb_io_close(f);
      }
-    rb_gc();
+    rb_gc_ifneeded();
  }

  void






In This Thread

Prev Next