mirror of
https://github.com/golang/go
synced 2024-11-25 13:27:57 -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,
|
ASTRING,
|
||||||
AINTER,
|
AINTER,
|
||||||
ANILINTER,
|
ANILINTER,
|
||||||
|
AMEMWORD,
|
||||||
|
|
||||||
BADWIDTH = -1000000000,
|
BADWIDTH = -1000000000,
|
||||||
MAXWIDTH = 1<<30
|
MAXWIDTH = 1<<30
|
||||||
|
@ -476,9 +476,13 @@ algtype(Type *t)
|
|||||||
int a;
|
int a;
|
||||||
|
|
||||||
if(issimple[t->etype] || isptr[t->etype] || iscomplex[t->etype] ||
|
if(issimple[t->etype] || isptr[t->etype] || iscomplex[t->etype] ||
|
||||||
t->etype == TCHAN || t->etype == TFUNC || t->etype == TMAP)
|
t->etype == TCHAN || t->etype == TFUNC || t->etype == TMAP) {
|
||||||
a = AMEM; // just bytes (int, ptr, etc)
|
if (t->width == widthptr) {
|
||||||
else if(t->etype == TSTRING)
|
a = AMEMWORD;
|
||||||
|
} else {
|
||||||
|
a = AMEM; // just bytes (int, ptr, etc)
|
||||||
|
}
|
||||||
|
} else if(t->etype == TSTRING)
|
||||||
a = ASTRING; // string
|
a = ASTRING; // string
|
||||||
else if(isnilinter(t))
|
else if(isnilinter(t))
|
||||||
a = ANILINTER; // nil interface
|
a = ANILINTER; // nil interface
|
||||||
|
@ -361,6 +361,24 @@ memcopy(uint32 s, void *a, void *b)
|
|||||||
ba[i] = bb[i];
|
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
|
static uintptr
|
||||||
strhash(uint32 s, String *a)
|
strhash(uint32 s, String *a)
|
||||||
{
|
{
|
||||||
@ -451,6 +469,7 @@ algarray[] =
|
|||||||
[ASTRING] { strhash, strequal, strprint, memcopy },
|
[ASTRING] { strhash, strequal, strprint, memcopy },
|
||||||
[AINTER] { interhash, interequal, interprint, memcopy },
|
[AINTER] { interhash, interequal, interprint, memcopy },
|
||||||
[ANILINTER] { nilinterhash, nilinterequal, nilinterprint, memcopy },
|
[ANILINTER] { nilinterhash, nilinterequal, nilinterprint, memcopy },
|
||||||
|
[AMEMWORD] { memhash, memwordequal, memprint, memwordcopy },
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma textflag 7
|
#pragma textflag 7
|
||||||
|
@ -307,6 +307,7 @@ enum
|
|||||||
ASTRING,
|
ASTRING,
|
||||||
AINTER,
|
AINTER,
|
||||||
ANILINTER,
|
ANILINTER,
|
||||||
|
AMEMWORD,
|
||||||
Amax
|
Amax
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user