私のテストが間違っていない限り、プレーン関数の使用を含む他のすべてのオプションは、埋め込みエイリアスを使用して別のパッケージのメソッドを定義するよりも約35%長くなります。私はおそらく何か間違ったことをしていて、それが何であるかを知りたいです。詳細はthis repositoryを参照してください。埋め込みエイリアスを使用して、異なるパッケージ内の構造体のメソッドを効率的に定義していますか?
[編集]コメント/提案ありがとうございました。以下は、「メソッド」と「meth」の比較に関連するコードのみを示しています。前者は、構造体とともにモデルパッケージで定義された典型的なメソッドを使用します。 "meth"オプションは、datactrlパッケージで定義された埋め込みエイリアスを使用するメソッドを定義します。最初のコード例には、構造体定義と、テストで使用される構造体のエクスポートされたデフォルトインスタンスが含まれています。パッケージモデルから
、ファイル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)
}
パッケージdatactrlから、パッケージのメインから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)
}
ファイル、ファイル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は平均40回のループをとり、各ループは100万回のテスト実行の平均を返します。記録のために、 "func"と "function"の両方のテストは、 "method"によって投稿された結果の2ms以内に完了します。
あなたのコードから見えるものは何ですか? 4つの事柄はすべてほぼ同じ時間に実行されます。 – zerkms
あなたはコードを最小限の問題と共有を説明するために必要なものに変換することができますか?https://play.golang.orgになるでしょう –
解体を見てみましたか?また、あなたのメソッドは、ポインタ受信機を取る、関数は値の引数を取る。このメソッドはポインタを渡し、関数は完全なオブジェクトに渡されます。コンパイラがその違いを最適化しない限り(これはそうではないと思われます)、それはパフォーマンスの違いを説明します –