몇 가지 Go(lang) 팁

3093 단어 godevelopment
Go(SEO를 위한 golang 스타일, 그렇지 않으면 아무것도 찾을 수 없음)는 꽤 훌륭한 언어입니다. 최대한 빨리 애플리케이션을 작성할 수 있도록 방해가 되는 언어입니다. 시작하는 데 필요한 모든 것을 제공하는 "배터리 포함"및 독단적인 에코시스템입니다.

나는 이 글을 주로 나 자신을 상기시키기 위해, 그 과정에서 내가 관찰한 몇 가지를 요약해서 쓰고 있습니다. 이것들은 아주 작은 세부 사항일 뿐입니다(그러나 실제로는 문제나 함정이 아니라 일반적인 팁일 뿐입니다). 나는 당신의 대부분이 이것에 대해 알고 있다고 확신합니다.

로그러스를 사용하지 마십시오



좋아, 이것은 Go의 일반적인 관행과 관련이 있습니다. 강력하고 정적으로 유형이 지정된 언어로서, 예를 들어 JS(Node) 또는 PHP에서와 같이 데이터 유형 주위를 휘젓는 것은 쉽지 않습니다. 제네릭이 부족하면 로거 또는 ORM에서 필요한 범용 코드를 작성하는 것이 매우 어렵고 사람들은 리플렉션에 의존합니다.

Logrus는 리플렉션을 많이 사용하므로 할당 수가 많습니다. 일반적으로 큰 문제는 아니지만(코드에 따라 다름) 사람들이 선택하는 이유는 성능이며 반사 문제를 피하면서 마이크로 최적화처럼 들릴 수 있습니다. 유형에 관계없이 구조체를 사용할 수 있는 것을 보면 리플렉션을 사용하므로 성능에 영향을 미칩니다.

예를 들어, Logrus는 유형에 대해 신경 쓰지 않지만 분명히 Go는 (결국) 알아야 합니다. Logrus는 오버헤드인 유형을 감지하기 위해 리플렉션을 사용합니다.

  log.WithFields(log.Fields{
    "animal": myWhatever,
  }).Info("A walrus appears")


무엇을 사용할지 내가 선호하지만 zerolog zap도 나쁘지 않습니다. 둘 다 제로 할당을 자랑합니다. 이는 애플리케이션에 가능한 가장 작은 영향을 미치는 작업에 대해 원하는 것입니다.

인코딩/json을 사용하지 마십시오



많은 사람들이 다른 것을 찾기 전에 표준 라이브러리를 사용할 것을 권장합니다. 나는 encoding/json 모듈을 예외라고 부른다. 위의 경우처럼 encoding/json는 리플렉션을 사용합니다. 이것은 비효율적이며 json 응답(또는 json 읽기/쓰기가 중요한 모든 종류의 마이크로 서비스)을 반환하는 API를 작성할 때 비용이 많이 들 수 있습니다.

몇 가지 대안/벤치마크를 살펴보십시오here.

무엇을 사용할 것인가Easyjson는 팩의 상단 정도이며 간단합니다. 효율적인 도구의 단점은 할당을 최소화하기 위해 구조체를 json으로 바꾸는 데 필요한 코드를 생성하기 위해 코드 생성을 사용한다는 것입니다. 이것은 성가신 수동 빌드 단계입니다. 흥미롭게도json-iterator 또한 리플렉션을 사용하지만 훨씬 빠릅니다. 흑마법이 의심됩니다.

클로저를 고루틴으로 사용하지 마십시오



다음은 기본 예제 코드입니다.

for i:=0;i<10;i++ {
  go func() {
     fmt.Println(i)
  }()
}


대부분의 사람들은 고루틴에 작업을 위임할 때와 같이 0에서 9까지의 숫자가 무작위로 인쇄될 것으로 예상할 수 있습니다.

실제 결과: 시스템에 따라 하나 또는 두 개의 숫자와 많은 10이 표시됩니다.

왜요?
  • 클로저는 상위 범위에 액세스할 수 있으므로 변수를 직접 사용할 수 있습니다. 업데이트된 린터가 "변수 클로저 캡처"
  • 에 대해 경고할 수 있지만 다시 선언하라는 메시지가 표시되지 않습니다.
  • Go의 성능 명성은 수행된 런타임 최적화에 많이 기인합니다. 여기서 수행하려는 작업을 "추측"하고 일부 실행 경로에 대해 최적화하려고 합니다. 이 동안 변수를 "캡처"하고 이론적으로 가장 효율적인 방식으로 필요한 곳에 전달합니다(예: 일부 CPU에서 할당을 해제하기 위해 일부 비동시 작업을 수행한 후). 이 경우의 결과는 루프가 고루틴을 시작하고 고루틴이 훨씬 나중에 상위 범위에서 액세스하는 i 값을 받을 수 있다는 것입니다. 이 코드를 몇 번 실행할 때 무엇을 보게 될지는 보장되지 않습니다(모든 10과 함께 임의의 값을 얻음).

  • 무엇을 사용해야 하는지 나는 이와 같은 클로저를 사용해야 할 이유를 잘 모르겠습니다. 자체 스택의 이점을 활용할 수 있는 함수를 만드는 것이 훨씬 더 깨끗하고 읽기 쉽습니다. 어떤 이유로든 클로저를 사용한다면 변수를 전달하십시오! 모든 함수와 마찬가지로 클로저를 처리하십시오.

    건배!

    좋은 웹페이지 즐겨찾기