[Go] 마초는'근육맨'이 아니에요.
마호패키지 봤어?이것은 마초이기 때문에 제목에서 호칭을 정확하게 이해하지 못하는 사람은 주의해야 한다.
배경: Performance regression이라는 Go1.15on MacOS의 Issue
동료 @budougumi0617은'내가 Go의 소스 코드를 읽을 때의 Tips'에서 Go Code Driving이 계속 개최하는 일을 소개했다.
이에 비해 당사는 BASE 구성원들과 정기적으로 Go Code Dreation 파티를 개최합니다.
한 사람이 해결할 수 없는 일은 모두 함께 보면 해결의 실마리를 찾을 수 있고, 다른 멤버들의 편집기를 훔칠 수도 있다.
12월 25일 오늘.ZU씨를 게스트로 모시고 테스팅 패키지 내 캐시 행동에 관해 읽은 뒤 잡담에서 "vim의 슬랙에서 예전에 @itchyny씨가 Go1.15에 도착했을 때 맥OS가 좀 느린 것 같아서 대단했다고 하더라"고 말했다.이 이슈인가'라는 주제로 진행된다.
응, 이 아이슈는 어떻게 해결했지?이게 시작이야.
248719: [release-branch.go1.15] cmd/link: link dynamic library automatically
제목의 Issue입니다.
이 아이슈의 차이는 다음과 같은 if문이다.
src/cmd/oldlink/internal/ld/go.go
if lib != "" && ctxt.HeadType == objabi.Hdarwin {
machoadddynlib(lib, ctxt.LinkMode)
}
현재 버전의 코드가 좀 이상합니다.if-else의 처리입니다.
src/cmd/oldlink/internal/ld/go.go
if local == "_" && remote == "_" {
// allow #pragma dynimport _ _ "foo.so"
// to force a link of foo.so.
havedynamic = 1
if ctxt.HeadType == objabi.Hdarwin {
machoadddynlib(lib, ctxt.LinkMode)
} else {
dynlib = append(dynlib, lib)
}
continue
}
objabi.Hdarwin
의 경우 즉 맥OS에 맞는 운영체제의 경우 machoadddynlib()
함수라고 하고 그렇지 않으면dynamic import을 진행한다는 내용이다.Issue는 다음을 나타냅니다.
Remove the unconditional imports in the runtime. Now,
Security.framework and CoreFoundation.framework are only linked
when the x509 package is imported (or otherwise specified).
모종의 경우처럼 필요 없는 import을 없애는 취지이기 때문에, Security.framework 및 CoreFoundation.프레임워크가 이런 행위를 제거한 것으로 추정된다.
이거, 동료 @glassemonkey씨 Swift씨CoreFoundation에서 잘 사용하고 있어요. 이런 정보 제공은 회의에서 그거에 맞는 녀석이라고 했어요.
이 PR의
src/runtime/sys_darwin.go
도 그 뜻을 이해할 수 있는 주석을 삭제하는 것을 확인할 수 있다.machoadddynlib
여기 나오는
macho
은 어떤 화제인가.결론적으로'근육남'은 아니다.이것은 "Mach-O"입니다.는 macOS 표준의 바이너리 파일 형식으로 사용되는 파일 형식입니다.
이번 이슈는 맥OS에 대한runtime이기 때문에'맥시-O'의 연관성은 점과 점에서 밀접하게 연결되어 있다.
포장은 debug/macho처럼 강력한 포장이 있다.
macho는 "표시·O"입니다.
마르크
여담: 테스트 포장과 gocachest
처음에 Testing Package에 대한 사연을 썼어요.budougumi0617에 이런 기사가 있어요~ Go 런타임 디버깅을 지원하는 환경 변수by@mattn랑 공유했어요.
gocachetest
는 캐시 테스트 결과에 대해 다시 사용할지 여부를 표시하는 옵션입니다.이것은 실제 내부에서 어떤 사용을 하는지에 대해 조금만 읽었다.우선
gochachetest
를 사용하면 다음 코드의 DebugTest
가 사실입니다.src/cmd/go/internal/cache/cache.go
func initEnv() {
verify = false
debugHash = false
debug := strings.Split(os.Getenv("GODEBUG"), ",")
for _, f := range debug {
if f == "gocacheverify=1" {
verify = true
}
if f == "gocachehash=1" {
debugHash = true
}
if f == "gocachetest=1" {
DebugTest = true
}
}
}
이후 테스트를 실행할 때
DebugTest
를 보고 로그를 출력하는 지점 코드를 분산시켰다.cmd/go/internal/test/test.go
func (c *runCache) tryCacheWithID(b *work.Builder, a *work.Action, id string) bool {
if len(pkgArgs) == 0 {
// Caching does not apply to "go test",
// only to "go test foo" (including "go test .").
if cache.DebugTest {
fmt.Fprintf(os.Stderr, "testcache: caching disabled in local directory mode\n")
}
c.disableCache = true
return false
}
그럼 Gopher 여러분 메리 크리스마스!
Reference
이 문제에 관하여([Go] 마초는'근육맨'이 아니에요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/hgsgtk/articles/3c81101c77ddf0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)