Gopherjs: Code with `defer` is 26x slower than without

Created on 26 May 2017  Â·  6Comments  Â·  Source: gopherjs/gopherjs

I understand that defer sentence must be executed whenever the function ends, but is it really needed to take care about JavaScript exceptions? The problem is performance. defer code is converted into a little complicated JS code with $methodVal and performance is not good.

In Go semantics, exception doesn't exist and, IIUC, GopherJS generates throw sentence only for panics. In most cases, like when no recover is called, defer is not called when panic-ing.

All 6 comments

performance is not good.

Do you have benchmarks to demonstrate this? It would be helpful to have a discussion about something concrete.

To answer your question, I don't know, this would require investigation. Perhaps @neelance knows more about this.

Defer is always called when panic-ing.

Dmitri Shuralyov notifications@github.com schrieb am Fr., 26. Mai 2017,
20:23:

performance is not good.

Do you have benchmarks to demonstrate this? It would be helpful to have a
discussion about something concrete.

To answer your question, I don't know, this would require investigation.
Perhaps @neelance https://github.com/neelance knows more about this.

—
You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
https://github.com/gopherjs/gopherjs/issues/648#issuecomment-304354993,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAA_ONBY9g-Pl5Tsy2e0q0I1mbhwCJj2ks5r9xi7gaJpZM4Nn6Vg
.

@shurcooL Here you are:

package test

import (
        "testing"
)

var i = 0

func begin() {
        i++
}

func end() {
        i--
}

func fooNormal() {
        begin()
        end()
}

func fooDefer() {
        begin()
        defer end()
}

func BenchmarkNormal(b *testing.B) {
        for i := 0; i < b.N; i++ {
                fooNormal()
        }
}

func BenchmarkDefer(b *testing.B) {
        for i := 0; i < b.N; i++ {
                fooDefer()
        }
}
$ gopherjs test --bench="." github.com/hajimehoshi/test
gopherjs: Source maps disabled. Install source-map-support module for nice stack traces. See https://github.com/gopherjs/gopherjs#gopherjs-run-gopherjs-test.
BenchmarkNormal         300000000                5.26 ns/op
BenchmarkDefer          10000000               137 ns/op
PASS
fatal error: all goroutines are asleep - deadlock!
FAIL    github.com/hajimehoshi/test     4.047s

Defer is always called when panic-ing.

I was misunderstanding. defer was actually called:

package main

func main() {
        defer println("defer is called")
        panic("panic!")
}
$ go run test.go 
defer is called
panic: panic!

goroutine 1 [running]:
main.main()
        /Users/hajimehoshi/go/src/github.com/hajimehoshi/test/test.go:5 +0x99
exit status 2

Thanks for the benchmark. I can reproduce results:

$ gopherjs test --bench=.
BenchmarkNormal     300000000            5.49 ns/op
BenchmarkDefer      10000000           138 ns/op
PASS
ok      github.com/shurcooL/play/31 4.280s
$ $ GOMAXPROCS=1 go test -bench=.
BenchmarkNormal     2000000000           1.80 ns/op
BenchmarkDefer      30000000            53.2 ns/op
PASS
ok      github.com/shurcooL/play/31 5.437s

So, with Go 1.8.3, gc compiler, the defer version is 29x slower. With GopherJS, the defer version is 25x slower.

That seems very reasonable to me, is it not?

Defer is a run-time mechanism and hast a small overhead. Depending on the context, it may or may not be expensive to use. As I wrote in https://dmitri.shuralyov.com/idiomatic-go#use-defer-if-its-overhead-is-relatively-negligible-or-it-buys-meaningful-readability, it should be used only when its overhead is relative negligible, or if it buys meaningful readability. Also see https://lk4d4.darth.io/posts/defer/.

Aha, I didn't realize defer costs so much even with the Go official compiler. Thanks, I'll close this issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

benechols-wf picture benechols-wf  Â·  6Comments

marwan-at-work picture marwan-at-work  Â·  4Comments

nytehauq picture nytehauq  Â·  7Comments

4ydx picture 4ydx  Â·  3Comments

canning-duck picture canning-duck  Â·  3Comments