Dig101-Go 之 interface 呼叫的一個優化點
檢視更多:歷史集錄
Dig101: dig more, simplified more and know more
今天談下上文 ( Dig101-Go 之讀懂 interface 的底層設計 ) 留下的那個問題:
為什麼對於以下 interface Stringer
和構造型別 Binary
下面程式碼conversion
會呼叫轉換函式convT64
,而devirt
不會呼叫?
func conversion() {
var b Stringer
var i Binary = 1
b = i //convT64
_=b.String()
}
func devirt() {
var b Stringer = Binary(1)
_ = b.String() //static call Binary.String
}
這裡可以使用 ssa 視覺化工具檢視,更容易瞭解每行程式碼的編譯過程 如
GOSSAFUNC=main go1.14 build types/interface/interface.go
生成ssa.html
事有蹊蹺,必是優化!
搜尋發現相關 issue Devirtualize calls when concrete type behind interface is statically known 和提交 De-virtualize interface calls
原來這個是為了優化如果 interface 內部的構造型別如果可以內聯後被靜態推斷出來的話,就將其直接重寫為靜態呼叫
最初主要希望避免一些 interface 呼叫的 gc 壓力(interface 呼叫在逃逸分析時,會使函式的接受者 (receiver
) 和引數 (argument
) 逃逸到堆上(而不是留在棧上),增加 gc 壓力。不過這一點目前還未實現,參見Use devirtualization in escape analysis)
暫時先優化為靜態呼叫避免轉換呼叫(convXXX
),減少程式碼大小和提升細微的效能
摘錄主要處理點如下:
// 對iface=類指標(pointer-shaped)構造型別 記錄itab
// 用於後續優化掉 OCONVIFACE
cmd/compile/internal/gc/subr.go:implements
if isdirectiface(t0) && !iface.IsEmptyInterface() {
itabname(t0, iface)
}
cmd/compile/internal/gc/reflect.go:itabname
itabs = append(itabs, itabEntry{t: t, itype: itype, lsym: s.Linksym()})
// 編譯前,獲取itabs
cmd/compile/internal/gc/reflect.go:peekitabs
// ssa時利用函式內聯和itabs推斷可重寫為靜態呼叫,避免convXXX
cmd/compile/internal/ssa/rewrite.go:devirt
Go 編譯步驟相關參見 Go compiler
這種優化對於常見的返回 interface 的建構函式還是有幫助的。
func New() Interface { return &impl{...} }
要注意返回構造型別需為類指標才可以。
我們可以利用這一點來應用此 interface 呼叫優化
想了解更多,可以檢視Devirtualize 的測試程式碼
本文程式碼見 NewbMiao/Dig101-Go
文章首發公眾號:newbmiao
推薦閱讀:Dig101-Go 系列
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- (桌面虛擬化最佳實踐–呼叫中心繫統優化之一)呼叫中心的特點優化
- Android效能優化之被忽視的優化點Android優化
- 一個sql的優化SQL優化
- 尾呼叫優化優化
- Oracle 優化重點(一)Oracle優化
- 一個效能優化的案例優化
- oracle優化一例之sql優化Oracle優化SQL
- 一個SQL優化SQL優化
- 站點優化之 WebP 實戰優化Web
- 發現一個開源專案優化點,點進來就是你的了優化
- 【MySQL】NOT EXISTS優化的一個案例MySql優化
- 一個SQL語句的優化SQL優化
- Golang之interfaceGolang
- 圖解尾呼叫優化圖解優化
- 遞迴尾呼叫優化遞迴優化
- 搭建 VuePress 站點必做的 10 個優化Vue優化
- 對於iOS效能優化的一點看法iOS優化
- Spring Cloud之微服務之間相互呼叫、如何讓一個微服務呼叫另外一個微服務SpringCloud微服務
- 19個MySQL效能優化要點解析MySql優化
- 【MySQL】效能優化之 order by (一)MySql優化
- 一個複合索引的優化案例索引優化
- 一個MySQL優化案例的初步思路MySql優化
- 函式呼叫的代價與優化函式優化
- 從Linux2.6.8核心的一個TSO/NATbug引出的網路問題排查觀點(附一個skb的優化點)Linux優化
- java之介面interfaceJava
- oracle之優化一用group by或exists優化distinctOracle優化
- 前端效能優化的點前端優化
- 記一個SQL優化案例SQL優化
- IPv6優點之層次化的地址結構
- 網格優化:潰堤之穴,一個也不能放過優化
- MSSQL優化之索引優化SQL優化索引
- CUDA優化之指令優化優化
- 一勞永逸的優化!併發RPC呼叫小工具優化RPC
- Java Web效能優化之一:減少DAO層的呼叫次數JavaWeb優化
- MySQL之SQL優化詳解(一)MySql優化
- 一個SQL效能問題的優化探索SQL優化
- MYSQL 阿里的一個sql優化問題MySql阿里優化
- 優化同事發過來的一個sql優化SQL