Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: &T{} generates different assembly than new(T) #16494

Closed
prashantv opened this issue Jul 25, 2016 · 3 comments
Closed

cmd/compile: &T{} generates different assembly than new(T) #16494

prashantv opened this issue Jul 25, 2016 · 3 comments

Comments

@prashantv
Copy link
Contributor

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)?
$ go version
go version go1.7rc3 darwin/amd64

(Also tested with go1.6.2)

  1. What operating system and processor architecture are you using (go env)?
    darwin/amd64
  2. What did you do?
    Create a simple struct User, and benchmark the difference between &User{} and new(User):
    https://github.com/prashantv/go-bench/blob/master/new_bench_test.go
  3. What did you expect to see?
    Both to have the same performance and disassembly.
  4. What did you see instead?
    new is consistently faster. Looking at the disassembly, new(User) does less work than &User{}.

new does:

MOVQ BX, 0(SP)
CALL runtime.newobject(SB)
MOVQ 0x8(SP), CX
MOVQ 0x40(SP), AX

and then increments the counter and jumps to the if check.

&User{} is similar but then also stores a lot of 0s before jumping to the if check:

MOVQ BX, 0(SP)
CALL runtime.newobject(SB)
MOVQ 0x8(SP), CX
XORL BP, BP
MOVQ BP, 0(CX)
MOVQ BP, 0x8(CX)
MOVQ BP, 0x10(CX)
MOVQ BP, 0x18(CX)
MOVQ BP, 0x20(CX)
MOVQ 0x40(SP), AX

It seems like &T{} is zeroing out the value even though runtime.newobject already returns a zero'ed out object.

@davecheney
Copy link
Contributor

I think this is a duplicate of a very similar issue I raised about 4-6
months ago.

On Tue, 26 Jul 2016, 07:34 Prashant Varanasi notifications@github.com
wrote:

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)?

$ go version
go version go1.7rc3 darwin/amd64

(Also tested with go1.6.2)

What operating system and processor architecture are you using (go env
)?
darwin/amd64
2.

What did you do?
Create a simple struct User, and benchmark the difference between
&User{} and new(User):
https://github.com/prashantv/go-bench/blob/master/new_bench_test.go
3.

What did you expect to see?
Both to have the same performance and disassembly.
4.

What did you see instead?
new is consistently faster. Looking at the disassembly, new(User) does
less work than &User{}.

new does:

MOVQ BX, 0(SP)
CALL runtime.newobject(SB)
MOVQ 0x8(SP), CX
MOVQ 0x40(SP), AX

and then increments the counter and jumps to the if check.

&User{} is similar but then also stores a lot of 0s before jumping to the
if check:

MOVQ BX, 0(SP)
CALL runtime.newobject(SB)
MOVQ 0x8(SP), CX
XORL BP, BP
MOVQ BP, 0(CX)
MOVQ BP, 0x8(CX)
MOVQ BP, 0x10(CX)
MOVQ BP, 0x18(CX)
MOVQ BP, 0x20(CX)
MOVQ 0x40(SP), AX

It seems like &T{} is zeroing out the value even though runtime.newobject
already returns a zero'ed out object.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#16494, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAcAyKc3f7BGHGxDG0MP-oLjncdGQ54ks5qZSvUgaJpZM4JUkkP
.

@freeformz
Copy link

dupe of #15199 ?

@davecheney
Copy link
Contributor

That's the one, closing as dup.

@golang golang locked and limited conversation to collaborators Jul 26, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants