[Golang] 함수 실행 시간 측정

golang에는 defer라는 예약어가 있습니다. defer로 지정된 함수 호출은, defer를 호출한 함수의 종료시에 호출되도록 보장한다는 것입니다. 이를 응용해서 함수의 실행 시간을 측정할 수 있는 범용성 있는 함수를 다음 코드처럼 만들 수 있습니다.

func ElapsedTime(tag string, msg string) func() {
    if msg != "" {
        log.Printf("[%s] %s", tag, msg)
    }

    start := time.Now()
    return func() { log.Printf("[%s] Elipsed Time: %s", tag, time.Since(start)) }
}

ElapsedTime 함수는 defer 문과 함께 사용되어야 의미가 있는데요. 이 함수를 호출하면 함수를 반환하게 되는데, 이 반환된 함수가 바로 defer 문을 통해 최종적으로 호출될 함수입니다. 이 함수를 테스트하기 위해 아래처럼 코드를 작성해 보겠습니다.

package main

import (
    "log"
    "time"
)

func bigSlowOperation() int {
    defer ElapsedTime("bigSlowOperation", "start")()

    time.Sleep(10 * time.Second) // 10초 정도 소요되는 연산에 해당하는 코드라 가정

    return 0
}

func ElapsedTime(tag string, msg string) func() {
    // 생략
}

func main() {
    bigSlowOperation()
}

크고 느린 연산를 호출하는 함수인 bigSlowOperation 함수 내부를 보면 defer 문으로 ElapsedTime 함수를 호출하여 반환된 함수를 호출하고 있습니다. 이를 통해 bigSlowOperation 호출이 끝나면 bigSlowOperation의 실행에 소요된 시간을 표시하게 되는데요. 그 결과는 아래와 같습니다.

2016/10/01 22:28:07 [bigSlowOperation] start
2016/10/01 22:28:17 [bigSlowOperation] Elipsed Time: 10.0007115s

[Golang] 명령줄에 대한 플래그 얻기(Command-Line Flag)

Go에서 만들어진 실행 파일을 실행할 때, 명령줄에 입력한 플래그 값을 쉽게 얻기 위해 제공하는 flag 패키지 사용에 대한 코드를 정리해 봅니다. 아래의 코드는 플래그로써 word, numb, fork에 값을 지정하고자 하는 경우입니다. word는 문자열, numb는 정수형, fork는 블린형으로 지정합니다.

package main

import (
    "flag"
    "fmt"
)

func main() {
    wordPtr := flag.String("word", "foo", "a string")
    numPtr := flag.Int("numb", 42, "an int")
    boolPtr := flag.Bool("fork", false, "a bool")

    flag.Parse()

    fmt.Println("word: ", *wordPtr)
    fmt.Println("numb: ", *numPtr)
    fmt.Println("fork: ", *boolPtr)
    fmt.Println("tail: ", flag.Args())
}

위의 프로그램을 컴파일해 실행 파일로 cmd_flag.exe가 만들어졌다고 할 때, 앞서 언급한 각 플래그에 값을 지정하여 실행한 예는 아래와 같습니다.

d:\__Working__\tstGo\cmd_flags>cmd_flags.exe -word=Hello -numb=23 -fork=true
word:  Hello
numb:  23
fork:  true
tail:  []

d:\__Working__\tstGo\cmd_flags>cmd_flags.exe -word="Hello World" -numb=23 -fork=true
word:  Hello World
numb:  23
fork:  true
tail:  []

d:\__Working__\tstGo\cmd_flags>cmd_flags.exe -word="Hello World" -numb=23 -fork=true a1 a2 a3
word:  Hello World
numb:  23
fork:  true
tail:  [a1 a2 a3]

d:\__Working__\tstGo\cmd_flags>cmd_flags.exe -word="Hello World" -numb=a -fork=true
invalid value "a" for flag -numb: strconv.ParseInt: parsing "a": invalid syntax
Usage of cmd_flags.exe:
  -fork
        a bool
  -numb int
        an int (default 42)
  -word string
        a string (default "foo")

d:\__Working__\tstGo\cmd_flags>