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

Reply via email to