[macruby-changes] [2964] MacRuby/trunk/hash.c

source_changes at macosforge.org source_changes at macosforge.org
Thu Nov 5 18:12:51 PST 2009


Revision: 2964
          http://trac.macosforge.org/projects/ruby/changeset/2964
Author:   lsansonetti at apple.com
Date:     2009-11-05 18:12:48 -0800 (Thu, 05 Nov 2009)
Log Message:
-----------
slightly faster hash iterations

Modified Paths:
--------------
    MacRuby/trunk/hash.c

Modified: MacRuby/trunk/hash.c
===================================================================
--- MacRuby/trunk/hash.c	2009-11-06 00:54:58 UTC (rev 2963)
+++ MacRuby/trunk/hash.c	2009-11-06 02:12:48 UTC (rev 2964)
@@ -91,25 +91,46 @@
 void
 rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
 {
-    CFIndex i, count;
-    const void **keys;
-    const void **values;
-
-    count = CFDictionaryGetCount((CFDictionaryRef)hash);
+    CFIndex count = CFDictionaryGetCount((CFDictionaryRef)hash);
     if (count == 0)
 	return;
 
-    keys = (const void **)alloca(sizeof(void *) * count);
-    values = (const void **)alloca(sizeof(void *) * count);
+    const void **keys = (const void **)alloca(sizeof(void *) * count);
+    const void **values = (const void **)alloca(sizeof(void *) * count);
 
     CFDictionaryGetKeysAndValues((CFDictionaryRef)hash, keys, values);
 
-    for (i = 0; i < count; i++) {
-	if ((*func)(OC2RB(keys[i]), OC2RB(values[i]), farg) != ST_CONTINUE)
+    for (CFIndex i = 0; i < count; i++) {
+	if ((*func)(OC2RB(keys[i]), OC2RB(values[i]), farg) != ST_CONTINUE) {
 	    break;
+	}
     }
 }
 
+struct rb_hash_iterate_context {
+    int (*func)(ANYARGS);
+    VALUE farg;
+};
+
+static void
+rb_hash_iterate_i(const void *key, const void *value, void *context)
+{
+    struct rb_hash_iterate_context *ctx =
+	(struct rb_hash_iterate_context *)context;
+
+    (*ctx->func)(OC2RB(key), OC2RB(value), ctx->farg); 
+}
+
+void
+rb_hash_iterate(VALUE hash, int (*func)(ANYARGS), VALUE farg)
+{
+    struct rb_hash_iterate_context ctx;
+    ctx.func = func;
+    ctx.farg = farg;
+    CFDictionaryApplyFunction((CFDictionaryRef)hash, rb_hash_iterate_i,
+	    &ctx); 
+}
+
 # define HASH_KEY_CALLBACKS(h) \
   ((CFDictionaryKeyCallBacks *)((uint8_t *)h + 52))
 
@@ -685,7 +706,7 @@
     args[0] = value;
     args[1] = Qnil;
 
-    rb_hash_foreach(hash, key_i, (st_data_t)args);
+    rb_hash_iterate(hash, key_i, (st_data_t)args);
 
     return args[1];
 }
@@ -907,7 +928,7 @@
 
     RETURN_ENUMERATOR(hash, 0, 0);
     result = rb_hash_new();
-    rb_hash_foreach(hash, select_i, result);
+    rb_hash_iterate(hash, select_i, result);
     return result;
 }
 
@@ -1043,7 +1064,9 @@
 static int
 each_value_i(VALUE key, VALUE value)
 {
-    if (key == Qundef) return ST_CONTINUE;
+    if (key == Qundef) {
+	return ST_CONTINUE;
+    }
     rb_yield(value);
     return ST_CONTINUE;
 }
@@ -1068,7 +1091,7 @@
 rb_hash_each_value(VALUE hash, SEL sel)
 {
     RETURN_ENUMERATOR(hash, 0, 0);
-    rb_hash_foreach(hash, each_value_i, 0);
+    rb_hash_iterate(hash, each_value_i, 0);
     return hash;
 }
 
@@ -1099,7 +1122,7 @@
 rb_hash_each_key(VALUE hash, SEL sel)
 {
     RETURN_ENUMERATOR(hash, 0, 0);
-    rb_hash_foreach(hash, each_key_i, 0);
+    rb_hash_iterate(hash, each_key_i, 0);
     return hash;
 }
 
@@ -1133,7 +1156,7 @@
 rb_hash_each_pair(VALUE hash, SEL sel)
 {
     RETURN_ENUMERATOR(hash, 0, 0);
-    rb_hash_foreach(hash, each_pair_i, 0);
+    rb_hash_iterate(hash, each_pair_i, 0);
     return hash;
 }
 
@@ -1159,27 +1182,25 @@
 static VALUE
 rb_hash_to_a(VALUE hash, SEL sel)
 {
-    VALUE ary;
+    VALUE ary = rb_ary_new();
+    rb_hash_iterate(hash, to_a_i, ary);
+    if (OBJ_TAINTED(hash)) {
+	OBJ_TAINT(ary);
+    }
 
-    ary = rb_ary_new();
-    rb_hash_foreach(hash, to_a_i, ary);
-    if (OBJ_TAINTED(hash)) OBJ_TAINT(ary);
-
     return ary;
 }
 
 static int
 inspect_i(VALUE key, VALUE value, VALUE str)
 {
-    VALUE str2;
-
     if (key == Qundef) {
 	return ST_CONTINUE;
     }
     if (RSTRING_LEN(str) > 1) {
 	rb_str_cat2(str, ", ");
     }
-    str2 = rb_inspect(key);
+    VALUE str2 = rb_inspect(key);
     rb_str_buf_append(str, str2);
     rb_str_buf_cat2(str, "=>");
     str2 = rb_inspect(value);
@@ -1191,13 +1212,11 @@
 static VALUE
 inspect_hash(VALUE hash, VALUE dummy, int recur)
 {
-    VALUE str;
-
     if (recur) {
 	return rb_usascii_str_new2("{...}");
     }
-    str = rb_str_buf_new2("{");
-    rb_hash_foreach(hash, inspect_i, str);
+    VALUE str = rb_str_buf_new2("{");
+    rb_hash_iterate(hash, inspect_i, str);
     rb_str_buf_cat2(str, "}");
     OBJ_INFECT(str, hash);
 
@@ -1239,7 +1258,9 @@
 static int
 keys_i(VALUE key, VALUE value, VALUE ary)
 {
-    if (key == Qundef) return ST_CONTINUE;
+    if (key == Qundef) {
+	return ST_CONTINUE;
+    }
     rb_ary_push(ary, key);
     return ST_CONTINUE;
 }
@@ -1259,11 +1280,8 @@
 static VALUE
 rb_hash_keys_imp(VALUE hash, SEL sel)
 {
-    VALUE ary;
-
-    ary = rb_ary_new();
-    rb_hash_foreach(hash, keys_i, ary);
-
+    VALUE ary = rb_ary_new();
+    rb_hash_iterate(hash, keys_i, ary);
     return ary;
 }
 
@@ -1276,7 +1294,9 @@
 static int
 values_i(VALUE key, VALUE value, VALUE ary)
 {
-    if (key == Qundef) return ST_CONTINUE;
+    if (key == Qundef) {
+	return ST_CONTINUE;
+    }
     rb_ary_push(ary, value);
     return ST_CONTINUE;
 }
@@ -1296,11 +1316,8 @@
 static VALUE
 rb_hash_values(VALUE hash, SEL sel)
 {
-    VALUE ary;
-
-    ary = rb_ary_new();
-    rb_hash_foreach(hash, values_i, ary);
-
+    VALUE ary = rb_ary_new();
+    rb_hash_iterate(hash, values_i, ary);
     return ary;
 }
 
@@ -1413,7 +1430,9 @@
 static int
 rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
 {
-    if (key == Qundef) return ST_CONTINUE;
+    if (key == Qundef) {
+	return ST_CONTINUE;
+    }
     rb_hash_aset(hash, value, key);
     return ST_CONTINUE;
 }
@@ -1434,7 +1453,6 @@
 rb_hash_invert(VALUE hash, SEL sel)
 {
     VALUE h = rb_hash_new();
-
     rb_hash_foreach(hash, rb_hash_invert_i, h);
     return h;
 }
@@ -1442,7 +1460,9 @@
 static int
 rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
 {
-    if (key == Qundef) return ST_CONTINUE;
+    if (key == Qundef) {
+	return ST_CONTINUE;
+    }
     rb_hash_aset(hash, key, value);
     return ST_CONTINUE;
 }
@@ -1450,7 +1470,9 @@
 static int
 rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
 {
-    if (key == Qundef) return ST_CONTINUE;
+    if (key == Qundef) {
+	return ST_CONTINUE;
+    }
     if (rb_hash_has_key_imp(hash, 0, key)) {
 	value = rb_yield_values(3, key, rb_hash_aref(hash, key), value);
     }
@@ -1519,7 +1541,9 @@
 static int
 assoc_i(VALUE key, VALUE val, VALUE *args)
 {
-    if (key == Qundef) return ST_CONTINUE;
+    if (key == Qundef) {
+	return ST_CONTINUE;
+    }
     if (RTEST(rb_equal(args[0], key))) {
 	args[1] = rb_assoc_new(key, val);
 	return ST_STOP;
@@ -1555,7 +1579,9 @@
 static int
 rassoc_i(VALUE key, VALUE val, VALUE *args)
 {
-    if (key == Qundef) return ST_CONTINUE;
+    if (key == Qundef) {
+	return ST_CONTINUE;
+    }
     if (RTEST(rb_equal(args[0], val))) {
 	args[1] = rb_assoc_new(key, val);
 	return ST_STOP;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091105/81f31997/attachment-0001.html>


More information about the macruby-changes mailing list