Created
          May 24, 2018 03:03 
        
      - 
      
- 
        Save nirui/82608ab20e5aac3bd3c1eb5a8f78d23c to your computer and use it in GitHub Desktop. 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | package main | |
| import ( | |
| "testing" | |
| "time" | |
| ) | |
| func BenchmarkTimeNow(b *testing.B) { | |
| for i := 0; i < b.N; i++ { | |
| time.Now() | |
| } | |
| } | |
| // goos: linux | |
| // goarch: amd64 | |
| // BenchmarkTimeNow-2 500000 3758 ns/op | 
> go version
go version devel +65c365bf0f Wed May 23 23:51:30 2018 +0000 linux/amd64
> go test -bench . -cpuprofile cpu.out
goos: linux
goarch: amd64
BenchmarkTimeNow-2   	  500000	      3753 ns/op
PASS
ok  	_/tmp/test	2.109s
> go tool pprof test.test cpu.out 
File: test.test
Type: cpu
Time: May 24, 2018 at 9:36pm (CST)
Duration: 2.10s, Total samples = 1.91s (90.78%!)(MISSING)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 1910ms, 100% of 1910ms total
      flat  flat%   sum%        cum   cum%
    1890ms 98.95% 98.95%     1890ms 98.95%  time.now
      20ms  1.05%   100%       60ms  3.14%  time.Now
         0     0%   100%       60ms  3.14%  _/tmp/test.BenchmarkTimeNow
         0     0%   100%       60ms  3.14%  testing.(*B).autodetectN
         0     0%   100%       60ms  3.14%  testing.(*B).launch
         0     0%   100%       60ms  3.14%  testing.(*B).runN
(pprof) list time.Now
Total: 1.91s
ROUTINE ======================== time.Now in /home/rany/Development/Tools/go/src/time/time.go
      20ms       60ms (flat, cum)  3.14% of Total
         .          .   1050:// Provided by package runtime.
         .          .   1051:func now() (sec int64, nsec int32, mono int64)
         .          .   1052:
         .          .   1053:// Now returns the current local time.
         .          .   1054:func Now() Time {
      20ms       60ms   1055:	sec, nsec, mono := now()
         .          .   1056:	sec += unixToInternal - minWall
         .          .   1057:	if uint64(sec)>>33 != 0 {
         .          .   1058:		return Time{uint64(nsec), sec + minWall, Local}
         .          .   1059:	}
         .          .   1060:	return Time{hasMonotonic | uint64(sec)<<nsecShift | uint64(nsec), mono, Local}
(pprof) list time.now
Total: 1.91s
ROUTINE ======================== time.now in /home/rany/Development/Tools/go/src/runtime/timestub.go
     1.89s      1.89s (flat, cum) 98.95% of Total
         .          .     12:
         .          .     13:import _ "unsafe" // for go:linkname
         .          .     14:
         .          .     15://go:linkname time_now time.now
         .          .     16:func time_now() (sec int64, nsec int32, mono int64) {
     980ms      980ms     17:	sec, nsec = walltime()
     910ms      910ms     18:	return sec, nsec, nanotime() - startNano
         .          .     19:}
(pprof) exit
> export GOROOT=/tmp/go1.8
> export PATH=/tmp/go1.8/bin
> go version
go version go1.8 linux/amd64
> go test -bench . -cpuprofile cpu.out 
BenchmarkTimeNow-2   	 1000000	      1825 ns/op
PASS
ok  	_/tmp/test	1.853s
> go tool pprof test.test cpu.out 
Entering interactive mode (type "help" for commands)
(pprof) top
1.83s of 1.83s total (  100%)
      flat  flat%   sum%        cum   cum%
     1.78s 97.27% 97.27%      1.78s 97.27%  runtime._ExternalCode
     0.04s  2.19% 99.45%      0.05s  2.73%  time.Now
     0.01s  0.55%   100%      0.01s  0.55%  time.now
         0     0%   100%      0.05s  2.73%  _/tmp/test.BenchmarkTimeNow
         0     0%   100%      1.78s 97.27%  runtime._System
         0     0%   100%      0.05s  2.73%  runtime.goexit
         0     0%   100%      0.05s  2.73%  testing.(*B).launch
         0     0%   100%      0.05s  2.73%  testing.(*B).runN
(pprof) list time.Now
Total: 1.83s
ROUTINE ======================== time.Now in /tmp/go1.8/src/time/time.go
      40ms       50ms (flat, cum)  2.73% of Total
         .          .    792:
         .          .    793:// Provided by package runtime.
         .          .    794:func now() (sec int64, nsec int32)
         .          .    795:
         .          .    796:// Now returns the current local time.
      10ms       10ms    797:func Now() Time {
      20ms       30ms    798:	sec, nsec := now()
      10ms       10ms    799:	return Time{sec + unixToInternal, nsec, Local}
         .          .    800:}
         .          .    801:
         .          .    802:// UTC returns t with the location set to UTC.
         .          .    803:func (t Time) UTC() Time {
         .          .    804:	t.setLoc(&utcLoc)
(pprof) list time.now
Total: 1.83s
ROUTINE ======================== time.now in /tmp/go1.8/src/runtime/sys_linux_amd64.s
      10ms       10ms (flat, cum)  0.55% of Total
         .          .    146:	JEQ	fallback
         .          .    147:	MOVL	$0, DI // CLOCK_REALTIME
         .          .    148:	LEAQ	0(SP), SI
         .          .    149:	CALL	AX
         .          .    150:	MOVQ	0(SP), AX	// sec
      10ms       10ms    151:	MOVQ	8(SP), DX	// nsec
         .          .    152:	MOVQ	AX, sec+0(FP)
         .          .    153:	MOVL	DX, nsec+8(FP)
         .          .    154:	RET
         .          .    155:fallback:
         .          .    156:	LEAQ	0(SP), DI
(pprof)
Also tested on Go 1.10.2 tarball downloaded directly from Golang website. It still slow but the profile information is differ.
> export GOROOT=/tmp/go1.10.2
> export PATH=/tmp/go1.10.2/bin
> go version
go version go1.10.2 linux/amd64
> go test -bench . -cpuprofile cpu.out
goos: linux
goarch: amd64
BenchmarkTimeNow-2   	  500000	      3632 ns/op
PASS
ok  	_/tmp/test	2.009s
> go tool pprof test.test cpu.out 
File: test.test
Type: cpu
Time: May 24, 2018 at 10:44pm (CST)
Duration: 2s, Total samples = 1.86s (92.86%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 1.86s, 100% of 1.86s total
      flat  flat%   sum%        cum   cum%
     1.76s 94.62% 94.62%      1.76s 94.62%  runtime._ExternalCode
     0.04s  2.15% 96.77%      0.04s  2.15%  runtime.nanotime
     0.04s  2.15% 98.92%      0.07s  3.76%  time.now
     0.01s  0.54% 99.46%      0.08s  4.30%  _/tmp/test.BenchmarkTimeNow
     0.01s  0.54%   100%      0.01s  0.54%  runtime.walltime
         0     0%   100%      1.78s 95.70%  runtime._System
         0     0%   100%      0.08s  4.30%  testing.(*B).launch
         0     0%   100%      0.08s  4.30%  testing.(*B).runN
         0     0%   100%      0.07s  3.76%  time.Now
(pprof) list time.Now
Total: 1.86s
ROUTINE ======================== time.Now in /tmp/go1.10.2/src/time/time.go
         0       70ms (flat, cum)  3.76% of Total
         .          .   1039:// Provided by package runtime.
         .          .   1040:func now() (sec int64, nsec int32, mono int64)
         .          .   1041:
         .          .   1042:// Now returns the current local time.
         .          .   1043:func Now() Time {
         .       70ms   1044:	sec, nsec, mono := now()
         .          .   1045:	sec += unixToInternal - minWall
         .          .   1046:	if uint64(sec)>>33 != 0 {
         .          .   1047:		return Time{uint64(nsec), sec + minWall, Local}
         .          .   1048:	}
         .          .   1049:	return Time{hasMonotonic | uint64(sec)<<nsecShift | uint64(nsec), mono, Local}
(pprof) list time.now
Total: 1.86s
ROUTINE ======================== time.now in /tmp/go1.10.2/src/runtime/timestub.go
      40ms       70ms (flat, cum)  3.76% of Total
         .          .     14:
         .          .     15:func walltime() (sec int64, nsec int32)
         .          .     16:
         .          .     17://go:linkname time_now time.now
         .          .     18:func time_now() (sec int64, nsec int32, mono int64) {
      20ms       20ms     19:	sec, nsec = walltime()
      20ms       50ms     20:	return sec, nsec, nanotime() - startNano
         .          .     21:}
(pprof) 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment
  
            
Discussion on the performance problem: https://groups.google.com/forum/#!topic/golang-nuts/7HybUAvUge4
Much more detail: