runtime: special case copy, equal for one-word interface values

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
This commit is contained in:
Kyle Consalus 2010-08-26 13:32:40 -04:00 committed by Russ Cox
parent ba5b09f786
commit 4d903504b3
4 changed files with 28 additions and 3 deletions

View File

@ -38,6 +38,7 @@ enum
ASTRING,
AINTER,
ANILINTER,
AMEMWORD,
BADWIDTH = -1000000000,
MAXWIDTH = 1<<30

View 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

View 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

View File

@ -307,6 +307,7 @@ enum
ASTRING,
AINTER,
ANILINTER,
AMEMWORD,
Amax
};