Wenn meine Tests nicht falsch sind, benötigen alle anderen Optionen, einschließlich der Verwendung von einfachen Funktionen, etwa 35% länger als Methoden in einem anderen Paket mit einem eingebetteten Alias definiert. Ich habe wahrscheinlich etwas falsch gemacht, und ich würde gerne wissen, was es ist. Für vollständige Details siehe this repository.Verwendet einen eingebetteten Alias, um Methoden auf einer Struktur in einem anderen Paket effizient zu definieren?
[EDIT] Danke für die Kommentare/Vorschläge. Das Folgende zeigt nur Code, der sich auf den Vergleich von "Methode" zu "Meth" bezieht. Ersteres verwendet typische Methoden, die im models-Paket zusammen mit dem struct definiert sind. Die Option "meth" definiert Methoden, die einen eingebetteten Alias verwenden, der im Paket datactrl definiert ist. Das erste Codebeispiel enthält die Strukturdefinition und eine exportierte Standardinstanz der in den Tests verwendeten Struktur.
von Paket-Modelle, Datei models.go
type CmntData struct {
ID int
Slug string
Title string
PageID int
Text string
DateCreated time.Time
CreatedBy int
}
var DefaultCD = CmntData{ID: 100, Title: "Demo Comment",
Text: "This is a test comment", PageID: 1000, CreatedBy: 4242}
// Local methods called by the "method" test
func (cd *CmntData) NewComment(ncd CmntData) *CmntData {
ncd.DateCreated = time.Now()
return &ncd
}
func (cd *CmntData) DefaultComment(cnt int) *CmntData {
dcd := DefaultCD
dcd.Slug = "demo-comment-" + strconv.Itoa(cnt + 1)
return cd.NewComment(dcd)
}
von Paket datactrl, Datei comments.go
// Types and method definitions used to add methods to models.CmntData
type roCmntData struct {
ModelCD models.CmntData
}
type roCD struct{}
// roComment allows us to effectively add methods to models.CmntData.
// Data and "local" methods defined for models.CmntData are accessible.
type roComment struct {
*roCmntData // Provides access to models.CmntData
*roCD // Required to make the magic happen
}
// Other packages must use Rcd to access methods added to models.CmntData
var Rcd = roComment {
roCmntData: &roCmntData{},
roCD: &roCD{},
}
// Remote methods called by the "meth" test
func (cd *roComment) NewComment(ncd models.CmntData) *models.CmntData {
cd.roCmntData.ModelCD = ncd
cd.ModelCD.DateCreated = time.Now()
return &cd.ModelCD
}
func (cd *roComment) DefaultComment(cnt int) *models.CmntData {
dcd := models.DefaultCD
dcd.Slug = "demo-comment-" + strconv.Itoa(cnt + 1)
return cd.NewComment(dcd)
}
von Paket Haupt, file main.go
if cmd == "method" {
tstart := time.Now()
dcd := models.CmntData{}
for i := 0; i < limit; i++ {
defCD = dcd.DefaultComment(i)
}
tfinish := time.Now()
elapsed = tfinish.Sub(tstart)
}
if cmd == "meth" {
tstart := time.Now()
// datactrl.Rcd provides access to remote models.CmntData methods
dcd := &datactrl.Rcd
for i := 0; i < limit; i++ {
defCD = dcd.DefaultComment(i)
}
tfinish := time.Now()
elapsed = tfinish.Sub(tstart)
}
Screen shot of results Der Durchschnitt von 40 Schleifen, wobei jede Schleife den Durchschnitt von einer Million Testläufen zurückgibt. Für die Aufzeichnung, beide "func" und "Funktion" Tests abgeschlossen innerhalb von 2ms von dem Ergebnis von "Methode".
Was soll man von Ihrem Code sehen? Alle 4 Dinge laufen ungefähr zur gleichen Zeit hier. – zerkms
Können Sie den Code auf das Minimum konvertieren, um das Problem zu veranschaulichen und zu teilen, könnte ein https://play.golang.org würde tun –
Haben Sie versucht, die Demontage zu betrachten? Außerdem: Ihre Methoden nehmen einen Zeigerempfänger, die Funktionen nehmen ein Wertargument. Der Methode wird ein Zeiger übergeben, den Funktionen wird das vollständige Objekt übergeben. Wenn der Compiler diesen Unterschied nicht optimiert (was ich nicht glaube), würde das den Unterschied in der Leistung erklären. –