Come noto, go non ha un tipo di unione e deve essere simulato solo tramite l'interfaccia.golang: come simulare efficacemente il tipo di unione
cerco due metodi per simulare l'unione, ma il risultato è tutt'altro che buono come C.
package main
import (
"fmt"
"time"
)
type U interface {
i32() int32
i16() int16
}
type i32 int32
func (u i32) i32() int32 {
return int32(u)
}
func (u i32) i16() int16 {
return int16(u)
}
type i16 int16
func (u i16) i32() int32 {
return int32(u)
}
func (u i16) i16() int16 {
return int16(u)
}
func test() (total int64) {
type A struct {
t int32
u interface{}
}
a := [...]A{{1, int32(100)}, {2, int16(3)}}
for i := 0; i < 5000000000; i++ {
p := &a[i%2]
switch p.t {
case 1:
total += int64(p.u.(int32))
case 2:
total += int64(p.u.(int16))
}
}
return
}
func test2() (total int64) {
type A struct {
t int32
u U
}
a := [...]A{{1, i32(100)}, {2, i16(3)}}
for i := 0; i < 5000000000; i++ {
p := &a[i%2]
switch p.t {
case 1:
total += int64(p.u.i32())
case 2:
total += int64(p.u.i16())
}
}
return
}
type testfn func() int64
func run(f testfn) {
ts := time.Now()
total := f()
te := time.Now()
fmt.Println(total)
fmt.Println(te.Sub(ts))
}
func main() {
run(test)
run(test2)
}
risultato:
257500000000
1m23.508223094s
257500000000
34.95081661s
Il modo in cui il metodo è migliore, e il tipo pressofuso modo costa più tempo della CPU.
La versione C:
#include <stdio.h>
struct A {
int t;
union {
int i;
short v;
} u;
};
long test()
{
struct A a[2];
a[0].t = 1;
a[0].u.i = 100;
a[1].t = 2;
a[1].u.v = 3;
long total = 0;
long i;
for (i = 0; i < 5000000000; i++) {
struct A* p = &a[i % 2];
switch(p->t) {
case 1:
total += p->u.i;
break;
case 2:
total += p->u.v;
break;
}
}
return total;
}
int main()
{
long total = test();
printf("%ld\n", total);
}
risultato:
257500000000
real 0m5.620s
user 0m5.620s
sys 0m0.000s
Il tipo unione è utile per molte applicazioni, ad esempio il protocollo di rete potrebbe contenere un tipo di calcestruzzo variante. Quindi, forse l'accesso ai dati di unione può diventare il collo di bottiglia dell'applicazione.
Chiunque può aiutare? Grazie.
Sì, può migliorare le prestazioni, ma a volte il tipo di variante può includere altri tipi, ad es. array di stringhe o byte. – kingluo
Vedi modifica. Ho rimosso gli usi di "non sicuro" poiché non è realmente necessario e ho aggiunto una nota su altri tipi. –
Grazie. Provo le funzioni binarie, sembrano molto costose. Dal momento che il sindacato non intende essere un formato wire, quindi la rappresentazione binaria non è necessaria per i tipi numerici. Penso che non sia più sicuro nel mio caso. – kingluo