mirror of
https://github.com/golang/go
synced 2024-11-12 04:30:22 -07:00
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:
parent
ba5b09f786
commit
4d903504b3
@ -38,6 +38,7 @@ enum
|
||||
ASTRING,
|
||||
AINTER,
|
||||
ANILINTER,
|
||||
AMEMWORD,
|
||||
|
||||
BADWIDTH = -1000000000,
|
||||
MAXWIDTH = 1<<30
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -307,6 +307,7 @@ enum
|
||||
ASTRING,
|
||||
AINTER,
|
||||
ANILINTER,
|
||||
AMEMWORD,
|
||||
Amax
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user