Beginner question concerning time.Now().Nanosecond()

1,617 views
Skip to first unread message

Saxo

unread,
Feb 7, 2013, 8:36:46 AM2/7/13
to golan...@googlegroups.com
Hello,

I want to measure the time some operation takes. So I basically do this:


start := time.Now().Nanosecond()
operation()
end := time.Now().Nanosecond()
fmt.Println(end - start)

Problem is that this approach seems to be wrong. I guess my understanding of what nanoseconds() does must be wrong. Some sample code:

package main

import (
    "fmt"
    "time"
)

func fib(n int) uint64 {
    if n < 2 {
        return 1
    }
    return (fib(n-1) + fib(n-2))
}


func main() {

    var n = 44
    for i := 0; i < 10; i++ {
        start := time.Now().Nanosecond()
        fib(n)
        end := time.Now().Nanosecond()
        fmt.Println(end - start)
    }

}
 
 This prints these values to the console (really true):

-46785700
-124911200
-78035900
921964100
89600
89600
-78035900
-46785700
-609282900
484467700

I don't understand what is happening here. Am using Go 1.0.3 on Windows. The times are also wrong, e.g. 484467700 nanosecs is about 484 millisecs. But fib(44) took about 10 seconds from looking on my watch.

Any hint appreciated.
Thanks, Oliver
 

minux

unread,
Feb 7, 2013, 8:40:47 AM2/7/13
to Saxo, golan...@googlegroups.com
On Thu, Feb 7, 2013 at 9:36 PM, Saxo <jet...@web.de> wrote:
I want to measure the time some operation takes. So I basically do this:


start := time.Now().Nanosecond()
operation()
end := time.Now().Nanosecond()
fmt.Println(end - start)
func (t Time) Nanosecond() int
    Nanosecond returns the nanosecond offset within the second specified by
    t, in the range [0, 999999999].

you just need to do this:
start := time.Now()
operation()
delta := time.Now().Sub(start)

or better, use the benchmark support in the testing package, it's much easier
than roll your own implementation.

Martin Angers

unread,
Feb 7, 2013, 8:47:37 AM2/7/13
to golan...@googlegroups.com
time.Now().Nanosecond() returns the nanosecond part of the time, or as mentioned in the doc, the "nanosecond offset within the second specified by t".


So if the end time has nanosecond 300 and the start time has nanosecond 400, you'll see a -100. What you should do is either take UnixNano(), or the preferred way to time a function, use a Benchmark function in a test file and run go test -b (http://golang.org/cmd/go/#hdr-Description_of_testing_functions).

Saxo

unread,
Feb 7, 2013, 8:51:26 AM2/7/13
to golan...@googlegroups.com, Saxo
I see, thanks for the answer. I now get these durations to calculation fibonacci 44:

13.8282135s
13.7344629s
14.0000896s
13.9844645s
14.0313398s
14.0782151s
14.0157147s
13.9375892s
13.7969633s
13.7344629s

Makes a lot more sense now ;-). Alas, fibonacci 44 takes with Java on the same machine 7984 ms (about 8 secs). I remember it is said somewhere on the Go homepage that code optimization will not be tackled before Go 1.1. So, not so bad for now.

-- Oliver

bryanturley

unread,
Feb 7, 2013, 2:11:55 PM2/7/13
to golan...@googlegroups.com, Saxo

Show us the code, perhaps we can make it faster.

minux

unread,
Feb 7, 2013, 2:13:01 PM2/7/13
to bryanturley, golan...@googlegroups.com, Saxo
On Fri, Feb 8, 2013 at 3:11 AM, bryanturley <bryan...@gmail.com> wrote:
Show us the code, perhaps we can make it faster. 
the code is in the first post.

and i'm afraid we can't make it faster without changing the algorithm. 

bryanturley

unread,
Feb 7, 2013, 2:29:59 PM2/7/13
to golan...@googlegroups.com, bryanturley, Saxo

Wow, how did I miss that.

Andy Balholm

unread,
Feb 7, 2013, 6:02:30 PM2/7/13
to golan...@googlegroups.com, bryanturley, Saxo
Basically, he's benchmarking function calls in Go vs. Java. I would guess that the difference is due to Go's split stacks.

bryanturley

unread,
Feb 7, 2013, 6:31:56 PM2/7/13
to golan...@googlegroups.com, bryanturley, Saxo
On Thursday, February 7, 2013 5:02:30 PM UTC-6, Andy Balholm wrote:
Basically, he's benchmarking function calls in Go vs. Java. I would guess that the difference is due to Go's split stacks.

Yeah after I read the code I was thinking that go doesn't yet do
http://en.wikipedia.org/wiki/Tail_recursion
Not sure about that though.

Andy Balholm

unread,
Feb 7, 2013, 8:22:06 PM2/7/13
to golan...@googlegroups.com, bryanturley, Saxo
On Thursday, February 7, 2013 3:31:56 PM UTC-8, bryanturley wrote:
Yeah after I read the code I was thinking that go doesn't yet do
http://en.wikipedia.org/wiki/Tail_recursion
Not sure about that though.

The Go compilers don't optimize tail calls, but this function isn't tail-recursive anyway. (The + operator needs to be executed after both recursive calls have returned.)

P.S. This is an extremely inefficient way to compute Fibonacci numbers, but I expect the OP knew that and was just looking for a way to burn some CPU time for his benchmark. 

Kyle Lemons

unread,
Feb 7, 2013, 9:50:55 PM2/7/13
to minux, Saxo, golang-nuts
or, slightly more simply:

start := time.Now()
op()
delta := time.Since(start)


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Russ Cox

unread,
Feb 7, 2013, 11:58:52 PM2/7/13
to Saxo, golang-nuts
It would probably help to benchmark something more representative of the program you would like to write. This particular benchmark is measuring a cost that almost never matters in real programs.

Russ

Saxo

unread,
Feb 8, 2013, 4:21:18 AM2/8/13
to golan...@googlegroups.com, Saxo
It would probably help to benchmark something more representative of the program you would like to write. This particular benchmark is measuring a cost that almost never matters in real programs.

Russ

Well, what I did was simply playing around a bit. It became public as I was asking this question about Nanoseconds(), but that doesn't incur that this fibonacci thing was intended to be serious. Nevertheless, I'm not sure whether the time a function call takes is that insignificant.

Is there a way to download current nightly builds of Go from somewhere? I found this: http://golang.org/doc/devel/weekly.html But you can't download the current pre-release Go 1.1. from there. I heard some first code optimization was done for Go 1.1. Would be interesting...

-- Oliver

Jan Mercl

unread,
Feb 8, 2013, 4:25:01 AM2/8/13
to Saxo, golang-nuts
On Fri, Feb 8, 2013 at 10:21 AM, Saxo <jet...@web.de> wrote:
> Is there a way to download current nightly builds of Go from somewhere? I
> found this: http://golang.org/doc/devel/weekly.html But you can't download
> the current pre-release Go 1.1. from there. I heard some first code
> optimization was done for Go 1.1. Would be interesting...

Check http://golang.org/doc/install/source and execute `hg up tip`
before doing `./all.bash`.

-j

Russ Cox

unread,
Feb 9, 2013, 11:04:21 AM2/9/13
to Saxo, golang-nuts
On Fri, Feb 8, 2013 at 4:21 AM, Saxo <jet...@web.de> wrote:
It would probably help to benchmark something more representative of the program you would like to write. This particular benchmark is measuring a cost that almost never matters in real programs.
Well, what I did was simply playing around a bit. It became public as I was asking this question about Nanoseconds(), but that doesn't incur that this fibonacci thing was intended to be serious. Nevertheless, I'm not sure whether the time a function call takes is that insignificant. 

By my count, your fib(44) program makes 2,269,806,339 function calls, so Java is taking 3.5 nanoseconds per call, and Go is taking 6.2 nanoseconds per call.

What I said was that it almost never matters in real programs, because real programs don't spend all their time making function calls: in a real program, the function being called does something, and that something will take significantly more than 6.2 nanoseconds.

Russ

Brendan Tracey

unread,
Feb 9, 2013, 3:01:42 PM2/9/13
to golan...@googlegroups.com, Saxo
Just curious, is there a document about best practices for writing efficient (computationally fast) Go programs? Is the answer that the language is still really new, so wait for a while until the compiler is better / more stable?

Thanks for all your work on this language, Russ. Overall coding time for me is longer because of the newness of the language (no scipy for go for example), but it's worth it.

Saxo

unread,
Feb 10, 2013, 12:46:45 PM2/10/13
to golan...@googlegroups.com, Saxo

By my count, your fib(44) program makes 2,269,806,339 function calls, so Java is taking 3.5 nanoseconds per call, and Go is taking 6.2 nanoseconds per call.

What I said was that it almost never matters in real programs, because real programs don't spend all their time making function calls: in a real program, the function being called does something, and that something will take significantly more than 6.2 nanoseconds.

Russ

Yes, I see your point, of course. Here is something to make people happy again. This Go code always prints 0 to the console no matter how often I run it:

func fibImperative(n int) uint64 {
    var x1 uint64 = 0
    var x2 uint64 = 1
    var tmp uint64 = 0

    for i := 1; i <= n+1; i++ {
        x1=x1+x2
        tmp=x2
        x2=x1
        x1=tmp
    }

    return x1;

}

func main() {
    var n = 44
    var duration time.Duration
    for i := 0; i < 50; i++ {
        start := time.Now()
        fibImperative(n)
        duration = time.Now().Sub(start)
        fmt.Println(duration)
    }
}
 

Wheras this Java code takes on average (50 invokations) about 2000 nanos:

    private static long fib(long n) {
        long x1 = 0;
        long x2 = 1;
        long tmp;
        for(long i=1;i<=n+1;i++) {
            x1=x1 + x2;
            tmp=x2; x2=x1; x1=tmp;
        }
        return x1;
    }

Each time calculating fib(44). So we can all be happy again ;-).

-- Saxo

Russ Cox

unread,
Feb 12, 2013, 9:01:16 AM2/12/13
to Brendan Tracey, golang-nuts, Saxo
On Sat, Feb 9, 2013 at 3:01 PM, Brendan Tracey <tracey....@gmail.com> wrote:
Just curious, is there a document about best practices for writing efficient (computationally fast) Go programs? Is the answer that the language is still really new, so wait for a while until the compiler is better / more stable?

No, I think the compilers are good enough to write efficient code today. Writing efficient code in Go is not much different than writing efficient code in any other language: get the algorithms right, and then profile your code to understand where it spends its time.


Russ
Reply all
Reply to author
Forward
0 new messages