Dan Sugalski wrote:
For the moment, I'd rather things stay the way they are. If we can produce demonstrable speed wins, then I'll change my mind.
I have some preliminary numbers:
- changed core.ops to include add_keyed [1]
- did implement add_keyed_int in array
- hacked set_pmc_keyed_int() to resemble the set_value approach [2]
- changed test program to do 10^5 add_keyed (+100 checks for ok)
$ time parrot a.pbc # 3 keyed emulation
ok
real 0m0.563s
$ time parrot k.pbc # 3 keyed opcode
ok
real 0m0.503s
So the direct add_keyed_int is ~10% faster then my proposal.
[1] This adds 9 opcodes. We still don't have the _kc variants.
[2] this breaks perl6's t/compiler/1_4, where proably a clone would help (it's a postincrement @z[0]++).
So, when looking at the size of just one method (~60 lines for just add_keyed_int) I can't imagine that implementing all these _keyed methods is the way to go.
leo
--- parrot/classes/array.pmc Mon Oct 21 15:23:30 2002
+++ parrot-leo/classes/array.pmc Tue Oct 22 13:05:56 2002
@@ -306,14 +306,23 @@
}
void set_pmc_keyed_int (INTVAL* dest_key, PMC* src, INTVAL* src_key) {
-
+ PMC* ptr;
if (!dest_key) {
return;
}
- Parrot_Array_set_pmc_ptr(INTERP, (List *) SELF->data, *dest_key);
+ ptr = Parrot_Array_set_pmc_ptr(INTERP, (List *) SELF->data, *dest_key);
if (src_key)
src = src->vtable->get_pmc_keyed_int(INTERP, src, src_key);
+ /* we have a valid value at this point, if src is a scalar,
+ * jus move the data over */
+ if (!src->data) {
+ mem_sys_memcopy(&ptr->cache.int_val, &src->cache.int_val,
+ sizeof(UnionVal));
+ ptr->vtable = src->vtable;
+ ptr->flags = src->flags;
+ }
+ else
list_assign(INTERP, (List *) SELF->data, *dest_key,
(void*)src, enum_type_PMC);
}
@@ -494,6 +503,71 @@
INTVAL is_equal_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key) {
/* XXX */
return 0;
+ }
+
+ void add_keyed_int (INTVAL* key, PMC* value, INTVAL* value_key, PMC* dest,
+INTVAL* dest_key) {
+ INTVAL i1, i2, i3;
+ FLOATVAL f1, f2, f3;
+ int type = enum_class_PerlInt;
+
+ if(value->vtable == &Parrot_base_vtables[enum_class_PerlNum]) {
+ type = enum_class_PerlNum;
+ }
+ else if(value->vtable == &Parrot_base_vtables[enum_class_PerlString]) {
+ f2 = value->vtable->get_number(INTERP, value);
+ i2 = value->vtable->get_integer(INTERP, value);
+ if(f2 != i2)
+ type = enum_class_PerlNum;
+ }
+ if (type == enum_class_PerlInt) {
+ if(SELF->vtable == &Parrot_base_vtables[enum_class_PerlNum]) {
+ type = enum_class_PerlNum;
+ }
+ else if(SELF->vtable == &Parrot_base_vtables[enum_class_PerlString]) {
+ f2 = SELF->vtable->get_number(INTERP, SELF);
+ i2 = SELF->vtable->get_integer(INTERP, SELF);
+ if(f2 != i2)
+ type = enum_class_PerlNum;
+ }
+ }
+ if (value_key) {
+ if (type == enum_class_PerlInt)
+ i3 = value->vtable->get_integer_keyed_int(INTERP, value, value_key);
+ else
+ f3 = value->vtable->get_number_keyed_int(INTERP, value, value_key);
+ }
+ else {
+ if (type == enum_class_PerlInt)
+ i3 = value->vtable->get_integer(INTERP, value);
+ else
+ f3 = value->vtable->get_number(INTERP, value);
+ }
+ if (key) {
+ if (type == enum_class_PerlInt)
+ i2 = SELF->vtable->get_integer_keyed_int(INTERP, SELF, key);
+ else
+ f2 = SELF->vtable->get_number_keyed_int(INTERP, SELF, key);
+ }
+ else {
+ if (type == enum_class_PerlInt)
+ i2 = SELF->vtable->get_integer(INTERP, SELF);
+ else
+ f2 = SELF->vtable->get_number(INTERP, SELF);
+ }
+ if (type == enum_class_PerlInt) {
+ i1 = i2 + i3;
+ if (key)
+ dest->vtable->set_integer_keyed_int(INTERP, dest, dest_key, i1);
+ else
+ dest->vtable->set_integer_native(INTERP, dest, i1);
+ }
+ else {
+ f1 = f2 + f3;
+ if (key)
+ dest->vtable->set_number_keyed_int(INTERP, dest, dest_key, i1);
+ else
+ dest->vtable->set_number_native(INTERP, dest, i1);
+ }
}
}
--- parrot/k.pasm Tue Oct 22 13:09:59 2002
+++ parrot-leo/k.pasm Tue Oct 22 10:58:12 2002
@@ -0,0 +1,31 @@
+_main:
+ new P0, 10 # .PerlArray
+ new P1, 10 # .PerlArray
+ new P2, 10 # .PerlArray
+ set I0, 0
+ set I1, 100000
+loop:
+ set P1[I0], I0
+ set P2[I0], I0
+ add P0[I0], P1[I0], P2[I0]
+ inc I0
+ le I0, I1, loop
+ set I0, 0
+lp2:
+ set I2, P0[I0]
+ shr I2, I2, 1
+ ne I0, I2, nok
+ add I0, I0, 100
+ le I0, I1, lp2
+ print "ok\n"
+ end
+nok:
+ print "nok "
+ print I0
+ print " "
+ print I2
+ print "\n"
+ end
+ ret
+
+
--- parrot/a.pasm Tue Oct 22 13:09:59 2002
+++ parrot-leo/a.pasm Tue Oct 22 11:01:46 2002
@@ -0,0 +1,35 @@
+_main:
+ new P0, 10 # .PerlArray
+ new P1, 10 # .PerlArray
+ new P2, 10 # .PerlArray
+ set I0, 0
+ set I1, 100000
+ new P3, 15 # .PerlUndef
+loop:
+ set P1[I0], I0
+ set P2[I0], I0
+ set P5, P1[I0]
+ set P4, P2[I0]
+ add P3, P5, P4
+ set P0[I0], P3
+ inc I0
+ le I0, I1, loop
+ set I0, 0
+lp2:
+ set I2, P0[I0]
+ shr I2, I2, 1
+ ne I0, I2, nok
+ add I0, I0, 100
+ le I0, I1, lp2
+ print "ok\n"
+ end
+nok:
+ print "nok "
+ print I0
+ print " "
+ print I2
+ print "\n"
+ end
+ ret
+
+
