Best way of parsing date and time in golang
date, go, parsing, performance, time
Solution
I would expect to make your entire program much faster. For example, `ParseDate3`,
func ParseDate3(date []byte) (time.Time, error) {
year := (((int(date[0])-'0')*10+int(date[1])-'0')*10+int(date[2])-'0')*10 + int(date[3]) - '0'
month := time.Month((int(date[5])-'0')*10 + int(date[6]) - '0')
day := (int(date[8])-'0')*10 + int(date[9]) - '0'
hour := (int(date[11])-'0')*10 + int(date[12]) - '0'
minute := (int(date[14])-'0')*10 + int(date[15]) - '0'
second := (int(date[17])-'0')*10 + int(date[18]) - '0'
return time.Date(year, month, day, hour, minute, second, 0, time.UTC), nil
}
Benchmarks:
$ go test -bench=.
testing: warning: no tests to run
PASS
BenchmarkParseDate1 5000000 308 ns/op
BenchmarkParseDate2 10000000 225 ns/op
BenchmarkParseDate3 30000000 44.9 ns/op
ok so/test 5.741s
$ go test -bench=.
testing: warning: no tests to run
PASS
BenchmarkParseDate1 5000000 308 ns/op
BenchmarkParseDate2 10000000 226 ns/op
BenchmarkParseDate3 30000000 45.4 ns/op
ok so/test 5.757s
$ go test -bench=.
testing: warning: no tests to run
PASS
BenchmarkParseDate1 5000000 312 ns/op
BenchmarkParseDate2 10000000 225 ns/op
BenchmarkParseDate3 30000000 45.0 ns/op
ok so/test 5.761s
$
Reference:
Profiling Go Programs
If you insist on using `date string`, use `ParseDate4`,
func ParseDate4(date string) (time.Time, error) {
year := (((int(date[0])-'0')*10+int(date[1])-'0')*10+int(date[2])-'0')*10 + int(date[3]) - '0'
month := time.Month((int(date[5])-'0')*10 + int(date[6]) - '0')
day := (int(date[8])-'0')*10 + int(date[9]) - '0'
hour := (int(date[11])-'0')*10 + int(date[12]) - '0'
minute := (int(date[14])-'0')*10 + int(date[15]) - '0'
second := (int(date[17])-'0')*10 + int(date[18]) - '0'
return time.Date(year, month, day, hour, minute, second, 0, time.UTC), nil
}
Problem
I have a lot of datetime values incoming as string into my golang program. The format is fixed in number of digit: ``` 2006/01/02 15:04:05 ``` I started to parse these dates with the time.Parse function ``` const dtFormat = "2006/01/02 15:04:05" func ParseDate1(strdate string) (time.Time, error) { return time.Parse(dtFormat, strdate) } ``` but I had some performances issue with my program. Thus I tried to tune it by writting my own parsing function, taking into account that my format is kind of fixed: ``` func ParseDate2(strdate string) (time.Time, error) { year, _ := strconv.Atoi(strdate[:4]) month, _ := strconv.Atoi(strdate[5:7]) day, _ := strconv.Atoi(strdate[8:10]) hour, _ := strconv.Atoi(strdate[11:13]) minute, _ := strconv.Atoi(strdate[14:16]) second, _ := strconv.Atoi(strdate[17:19]) return time.Date(year, time.Month(month), day, hour, minute, second, 0, time.UTC), nil } ``` finally I did a benchmark on top of these 2 functions and got the following result: ``` BenchmarkParseDate1 5000000 343 ns/op BenchmarkParseDate2 10000000 248 ns/op ``` This is a performance improvement by 27%. Is there a better way in terms of performances that could improve such datetime parsing ?