흐르는 시간의 블로그...

GO언어를 가볍게 쓰고 있는 입장에서 JetBrains의 GoLand(이전에는 GogLand)는 참 좋은 도구이다.

비용을 들이지 않고 쓰는 개인버전이라 새버전이 나오면 열심히 업버전을 해서 사용중이다.

이전과 마찬가지로 업버전을 하고 GoLand를 실행하니 기존 코드들에 모두 빨간줄이 그어진다.

분명 GOROOT, GOPATH등 여러 변수를 확인해 봤는데 문제가 없다.

빨간줄이 그어져 있지만 컴파일도 잘 된다.

여기저기 찾아봤는데 쉽게 답이 보이지 않았다. (무쓸모 검색능력... )

그러다가 검색한 스택오버플로의 글이 보였다. 물론 나와는 좀 다른 이슈였다.

No buildable go source files after update Goland to EAP 19


선택된 답은 Fil 메뉴 --> Invalidate Caches 를 선택하라.

그래서 나도 해 봤다.

빨간줄 사라졌다.

혹여 이런 문제가 있으신 분들에게 도움이 되길 바라면서 이만~ 


페이스북의 GOLang 커뮤니티에서 아래의 글이 링크되었다.

Deferred Funcs

해당 글은 defer에 대해 매우 쉽게 잘 설명해주고 있다.

내용중에 인상적인 부분은 Deferred closure 이다.

최근 텍스트파일을 읽어서 데이터 분석을 했었다.

분석시 해당 데이터 전체의 시작과 끝점을 기록할 필요가 있었다.

문제는 끝점이 정확히 검색이 되는 경우이지만 그렇지 않은 경우 여러 조건절을 통해 끝점을 찾아야 한다.

나쁜 경우는 내용전체를 돌면서 최종 기록을 끊임없이 반복하여 기존 변수에 할당해야 하는 것이다.


for err != io.EOF {
if xxxx { ...... ......
(CarsInfo[lID][dDate][rNo]).endTime = "20" + string(lines[11:23])
beforeSpeed = nowSpeed
}

n, err = rc.Read(lines) } // 마지막 라인 if xxx { (CarsInfo[lID][dDate][rNo]).endTime = "20" + string(lines[11:23]) }

이런 경우 deferred closure를 사용하면 성능을 좋게하면서 코드를 깔끔하게 할 수 있다.

위의 링크의 예제코드이다.

defer func() 내에서 조건문을 사용하여 작업을 할수도 있고 정해진 구조라면 마지막의 일부 데이터만 추출하여 사용할 수 있다.

만약  for 루프가 10000번 실행된다면 10000번의 할당작업의 성능을 아낄수 있다.


defer func () {

(CarsInfo[lID][dDate][rNo]).endTime = "20" + string(lines[11:23])

}() for err != io.EOF {
if xxxx { ...... ......
beforeSpeed = nowSpeed
}

n, err = rc.Read(lines) }


현재 개인적으로 개발한 분석 코드에서의 수정 결과를 체크해보자.

할당에 대한 CPU 타임은 크지 않으므로 아주 큰 효과는 없으리라 본다.


테스트 환경 / 결과

12코어(TOP 표기상 24코어)중 절반 사용

평소 100% idle (완벽히 노는 서버)

worker 20개로 버퍼채널 이용

20398개의 ZIP 파일을 zip package를 이용해서 압축을 풀면서 분석

캐쉬 상황을 고려하여 번갈아가며 3회 반복(압축을 풀면서 작업하기에 캐쉬관련 이슈는 없지 싶지만서도...)

평균 15초 이상 줄어든다

기존 코드 결과

job ends. execute time: 3m14.353966626s

job ends. execute time: 3m16.453676824s

job ends. execute time: 3m15.367271724s

deferred closure 사용 결과

job ends. execute time: 3m0.899630867s

job ends. execute time: 2m59.410079684s

job ends. execute time: 2m52.597714407s


결론

꽤 괜찮다. 적극적으로 사용할만한 패턴이라 생각된다.

출처: https://www.facebook.com/groups/golangko/permalink/831834226994058/


type foo struct{

⠀⠀⠀⠀a int
⠀⠀⠀⠀b int
⠀⠀⠀⠀c int
⠀⠀⠀⠀_ struct{} // to prevent unkeyed literals
}


이렇게 정의하면 필드 이름 없이 선언(unkeyed literals) 하는걸 방지해준다고 하네요.
⠀⠀
⠀⠀
foo{1,2,3}하면 컴파일러가 
⠀⠀
"too few values in struct initializer"라는 에러를 내뿜습니다.
⠀⠀
foo{a:1,b:2,c:3}같이 필드 이름을 꼭 써줘야 합니다.
⠀⠀
필드 순서가 중요한 struct들을 정의 할 때 사용하는 트릭이라네요

GOLang으로 첫번째 프로젝트를 진행했다.

프로젝트라고 할것까지 없는 사실 C++로 했으면 두시간짜리를 거의 며칠에 걸쳐서 했다.

다음에는 빨라질꺼라 기대를 하며... 작업을 진행했다.


과정에서 느낀점 몇가지는 아래와 같다. 

(매우 간단한 프로젝트였다는 점을 감안하자)

  • File 관련 작업이 매우 편리하다
  • JSON으로 출력하는 것도 매우 편리하다
  • 기본 라이브러리만 가지고 한다면 이종(linux/windows)간에도 매우 편리하다
  • 하나의 패키지 내에서 파일의 분포나 기능의 분할이 아직은 낯설다
  • 파일 분리가 엉망으로 된 것 같다
  • CentOS에서 인스톨할때 편리하다 - yum 사용
  • yum으로 인스톨할 경우 GOROOT가 잡는게 난감했다(맞는건지 모르겠다) - /usr/lib/golang
  • 간단하게나마 로그파일을 남겼다
  • 스택오버플로우는 진리다!