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 + +