<p>Imagine the following code:</p>
<pre><code>type User struct {
// ...
}
func (User) TableName() string {
return "users"
}
</code></pre>
<p>Is the struct copied when the function above is executed? Or the compiler is smart enough to prevent it? Would have a performance benefit using a pointer instead?</p>
<pre><code>func (*User) TableName() string {
return "users"
}
</code></pre>
<hr/>**评论:**<br/><br/>TheMerovius: <pre><p>This is unspecified. You should rely neither on the copy being performed, nor on it not being performed.</p>
<p>You also should measure if it's a performance problem (and I assume you haven't done that, otherwise you presumably wouldn't ask the question) and only worry about it, if it is.</p></pre>schumacherfm: <pre><p>and also less pointer usage causes less GC sweeps. So copying is often fine when writing is not or hardly required.</p></pre>barsonme: <pre><p>For a copy not to be made the compiler would need to inline <code>TableName</code> <em>or</em> do some spooky stuff and modify <code>TableName</code>.</p>
<p>What I mean by the latter is since <code>t.M()</code> is equivalent to <code>M(t)</code>, the compiler would have to recognize that <code>t</code> is never used and change all invocations of <code>t.M()</code> to just <code>M()</code>.</p>
<p>I doubt the compiler does or will do that (granted the spec does not say anything either way).</p></pre>el-chupa: <pre><p>No need to guess...</p>
<pre><code>package p
type User struct {
// ...
}
func (User) TableName() string {
return "users"
}
$ go build -gcflags='-m'
# _/tmp
./a.go:7: can inline User.TableName
<autogenerated>:1: inlining call to User.TableName
<autogenerated>:1: (*User).TableName .this does not escape
</code></pre></pre>barsonme: <pre><p>that only proves the implementation, though. And we all know inlining is going to happen, at least with OP's example. The important bit of my comment was whether the compiler can rewrite function calls to omit parameters.</p></pre>el-chupa: <pre><blockquote>
<p>that only proves the implementation, though.</p>
</blockquote>
<p>Isn't that what discussion is about (implementation details)?</p>
<blockquote>
<p>And we all know inlining is going to happen at least with OP's example</p>
</blockquote>
<p>No, we don't; that's an implementation detail as well.</p>
<blockquote>
<p>The important bit of my comment was whether the compiler can rewrite function calls to omit parameters.</p>
</blockquote>
<p>Also an implementation detail...</p></pre>barsonme: <pre><p>I wasn't trying to prove that a the complier might do <em>X</em>, I was suggesting the compiler can't do <em>X</em>.</p></pre>TheMerovius: <pre><blockquote>
<p>I doubt the compiler does or will do that (granted the spec does not say anything either way).</p>
</blockquote>
<p>Inlining is already happening, from there it's a trivial optimization to realize that there needs to be no copy. I would actually be surprised if the compiler <em>doesn't</em> optimize it away (unless you have an indirection via an interface. But even then, it should be trivial). But the spec doesn't say, so it's an implementation detail, so you shouldn't rely on it.</p></pre>barsonme: <pre><p>By definition inlining removes the copy. </p>
<p>Ignoring inlining, there's no way to prevent a copy without some spooky compiler magic. </p></pre>Matthias247: <pre><p>It's actually not too spooky. The compiler can simply try to figure out whether the parameter is ever written to or whether it escapes. If not it could freely change the signature to a pointer type if it thinks it would benefit the performance. Not sure whether the compiler is doing anything like that. The ability of being able to call functions via reflection might prohibit such changes.</p></pre>barsonme: <pre><p>I was assuming removing parameters instead of taking the address which I the spec says the compiler does automatically in specific scenarios. </p>
<p>Yes, one of the biggest issue with rewriting anything is reflection—the function that reflection looks up needs to be identical to the one the user expects they're calling. Thus the spooky
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
0 回复
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传