Project

General

Profile

Bug #14263 » array-eql-by-hash.patch

Patch to compare by hash in Array set operations for all array sizes - styrmis (Stefan Magnuson), 03/25/2018 09:38 PM

View differences:

array.c
}
static VALUE
rb_ary_includes_by_eql(VALUE ary, VALUE item)
rb_ary_includes_by_hash(VALUE ary, VALUE item)
{
long i;
VALUE e;
VALUE e, item_hash, e_hash;
ID id_hash = rb_intern("hash");
item_hash = rb_funcall(item, id_hash, 0);
for (i=0; i<RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
if (rb_eql(item, e)) {
return Qtrue;
}
e = RARRAY_AREF(ary, i);
e_hash = rb_funcall(e, id_hash, 0);
if (rb_eql(item_hash, e_hash)) {
return Qtrue;
}
}
return Qfalse;
}
......
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
for (i=0; i<RARRAY_LEN(ary1); i++) {
VALUE elt = rb_ary_elt(ary1, i);
if (rb_ary_includes_by_eql(ary2, elt)) continue;
if (rb_ary_includes_by_hash(ary2, elt)) continue;
rb_ary_push(ary3, elt);
}
return ary3;
......
if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
for (i=0; i<RARRAY_LEN(ary1); i++) {
v = RARRAY_AREF(ary1, i);
if (!rb_ary_includes_by_eql(ary2, v)) continue;
if (rb_ary_includes_by_eql(ary3, v)) continue;
if (!rb_ary_includes_by_hash(ary2, v)) continue;
if (rb_ary_includes_by_hash(ary3, v)) continue;
rb_ary_push(ary3, v);
}
return ary3;
......
ary3 = rb_ary_new();
for (i=0; i<RARRAY_LEN(ary1); i++) {
VALUE elt = rb_ary_elt(ary1, i);
if (rb_ary_includes_by_eql(ary3, elt)) continue;
if (rb_ary_includes_by_hash(ary3, elt)) continue;
rb_ary_push(ary3, elt);
}
for (i=0; i<RARRAY_LEN(ary2); i++) {
VALUE elt = rb_ary_elt(ary2, i);
if (rb_ary_includes_by_eql(ary3, elt)) continue;
if (rb_ary_includes_by_hash(ary3, elt)) continue;
rb_ary_push(ary3, elt);
}
return ary3;
(3-3/4)