]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: special case copy, equal for one-word interface values
authorKyle Consalus <consalus@gmail.com>
Thu, 26 Aug 2010 17:32:40 +0000 (13:32 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 26 Aug 2010 17:32:40 +0000 (13:32 -0400)
Based on the observation that a great number of the types that
are copied or compared in interfaces, maps, and channels are
word-sized, this uses specialized copy and equality functions
for them that use a word instead of 4 or 8 bytes. Seems to yield
0-6% improvements in performance in the benchmarks I've run.
For example, with the regexp benchmarks:

Before:
regexp.BenchmarkLiteral   500000       3.26 µs/op
regexp.BenchmarkNotLiteral    100000      13.67 µs/op
regexp.BenchmarkMatchClass    100000      18.72 µs/op
regexp.BenchmarkMatchClass_InRange    100000      20.04 µs/op
regexp.BenchmarkReplaceAll    100000      27.85 µs/op

After:
regexp.BenchmarkLiteral   500000       3.11 µs/op
regexp.BenchmarkNotLiteral    200000      13.29 µs/op
regexp.BenchmarkMatchClass    100000      17.65 µs/op
regexp.BenchmarkMatchClass_InRange    100000      18.49 µs/op
regexp.BenchmarkReplaceAll    100000      26.34 µs/op

R=rsc
CC=golang-dev
https://golang.org/cl/1967047

src/cmd/gc/go.h
src/cmd/gc/subr.c
src/pkg/runtime/runtime.c
src/pkg/runtime/runtime.h

index 581a3eb37b8555fca289d573f55754a61a345838..e87c4c9804022d3ab005f128ab4d4dd79819bcfd 100644 (file)
@@ -38,6 +38,7 @@ enum
        ASTRING,
        AINTER,
        ANILINTER,
+       AMEMWORD,
 
        BADWIDTH        = -1000000000,
        MAXWIDTH        = 1<<30
index 1c0bf1a8cc7aabb66c32e06d548017ee324d8aad..ec0b869fca60e3d500c89b2abe55f0f188c75d31 100644 (file)
@@ -476,9 +476,13 @@ algtype(Type *t)
        int a;
 
        if(issimple[t->etype] || isptr[t->etype] || iscomplex[t->etype] ||
-          t->etype == TCHAN || t->etype == TFUNC || t->etype == TMAP)
-               a = AMEM;       // just bytes (int, ptr, etc)
-       else if(t->etype == TSTRING)
+               t->etype == TCHAN || t->etype == TFUNC || t->etype == TMAP) {
+               if (t->width == widthptr) {
+                       a = AMEMWORD;
+               } else {
+                       a = AMEM;       // just bytes (int, ptr, etc)
+               }
+       } else if(t->etype == TSTRING)
                a = ASTRING;    // string
        else if(isnilinter(t))
                a = ANILINTER;  // nil interface
index 25a6f26bdf9cdc8f3f1efbb0869a5137b4576f3a..71eb8d6b56789af4053265277a7fbe7536e3b9af 100644 (file)
@@ -361,6 +361,24 @@ memcopy(uint32 s, void *a, void *b)
                ba[i] = bb[i];
 }
 
+static uint32
+memwordequal(uint32 s, void *a, void *b)
+{
+       USED(s);
+       return *(uintptr*)(a) == *(uintptr*)(b);
+}
+
+static void
+memwordcopy(uint32 s, void *a, void *b)
+{
+       USED(s);
+       if (b == nil) {
+               *(uintptr*)(a) = 0;
+               return;
+       }
+       *(uintptr*)(a) = *(uintptr*)(b);
+}
+
 static uintptr
 strhash(uint32 s, String *a)
 {
@@ -451,6 +469,7 @@ algarray[] =
 [ASTRING]      { strhash, strequal, strprint, memcopy },
 [AINTER]               { interhash, interequal, interprint, memcopy },
 [ANILINTER]    { nilinterhash, nilinterequal, nilinterprint, memcopy },
+[AMEMWORD] { memhash, memwordequal, memprint, memwordcopy },
 };
 
 #pragma textflag 7
index 0e4adafb35553152738b1762b1ddead3ad5ed913..8d88716a45124ba134ed86e9e7d44a4312370ce3 100644 (file)
@@ -307,6 +307,7 @@ enum
        ASTRING,
        AINTER,
        ANILINTER,
+       AMEMWORD,
        Amax
 };