我目前正在使用GoLang创建游戏。我正在测量FPS。我注意到使用for循环将7 fps损失附加到切片上,如下所示:
vertexInfo := Opengl.OpenGLVertexInfo{}
for i := 0; i < 4; i = i + 1 {
vertexInfo.Translations = append(vertexInfo.Translations, float32(s.x), float32(s.y), 0)
vertexInfo.Rotations = append(vertexInfo.Rotations, 0, 0, 1, s.rot)
vertexInfo.Scales = append(vertexInfo.Scales, s.xS, s.yS, 0)
vertexInfo.Colors = append(vertexInfo.Colors, s.r, s.g, s.b, s.a)
}
我正在为每个精灵,每个平局做这些。问题是,为什么只循环几次并将相同的内容附加到这些切片中,我会得到如此巨大的性能影响?有没有更有效的方法可以做到这一点?这不像我要添加大量数据。每个切片包含大约16个元素,如上所示(4
x 4)。
当我简单地将所有16个元素合而为一时,[]float32{1..16}
fps大约提高了4。
更新: 我对每个附录进行了基准测试,似乎每个附录都要以1 fps的速度执行。考虑到此数据是非常静态的,这似乎很多。我只需要进行4次迭代…
更新: 添加了github repo
https://github.com/Triangle345/GT
append()
如果目标切片的容量小于追加后切片的长度,则内置函数需要创建一个新的后备阵列。这也需要将当前元素从目标复制到新分配的数组,因此开销很大。
由于使用切片文字来创建Opengl.OpenGLVertexInfo
值,因此追加到的切片很可能是空切片。即使append()
为将来考虑并分配了比添加指定元素所需的数组更大的数组,但在您的情况下,很可能需要多次重新分配才能完成4个迭代。
如果这样创建和初始化,则可以避免重新分配vertexInfo
:
vertexInfo := Opengl.OpenGLVertexInfo{
Translations: []float32{float32(s.x), float32(s.y), 0, float32(s.x), float32(s.y), 0, float32(s.x), float32(s.y), 0, float32(s.x), float32(s.y), 0},
Rotations: []float64{0, 0, 1, s.rot, 0, 0, 1, s.rot, 0, 0, 1, s.rot, 0, 0, 1, s.rot},
Scales: []float64{s.xS, s.yS, 0, s.xS, s.yS, 0, s.xS, s.yS, 0, s.xS, s.yS, 0},
Colors: []float64{s.r, s.g, s.b, s.a, s.r, s.g, s.b, s.a, s.r, s.g, s.b, s.a, s.r, s.g, s.b, s.a},
}
还要注意,此struct文字将不必在切片后重新分配数组。但是,如果在代码的其他位置(我们看不到),您将更多元素附加到这些片中,则可能会导致重新分配。如果是这种情况,则应创建容量更大的片,以覆盖“未来”分配(例如make([]float64, 16, 32)
)。
问题内容: 我终于在代码中发现了性能瓶颈,但是对于原因是很困惑的。为了解决这个问题,我将所有对的调用都改为使用。但是为什么太慢了? 例如(注意在电话): 但是奇怪的是,写入使用创建的数组要慢于使用创建的数组: 我的猜测是使用一些CPU技巧,而不是实际写入内存来分配它。写入时可以即时完成。但这仍不能解释数组创建时间的巨大差异。 我正在使用当前的numpy版本运行Mac OS X Yosemite:
以下代码的输出令我惊讶: 在操场上运行时(https://play.golang.org/p/Ph67tHOt2Z_I)输出如下: 我相信我对切片的处理是正确的;据我所知,它在NewThing()中被初始化为nil,并在Add()中被追加(确保从append返回的值只分配给它的第一个参数)。 我错过了一些非常明显的东西吗? 我查看了以下资源以获得解释: https://gobyexample.co
问题内容: 我今天在go代码中遇到了奇怪的行为:当我追加到in循环中,然后尝试根据循环的结果创建new时,最后一个重写了previous 。 在这个特殊的例子这意味着 ,和切片的最后一个元素都没有,和分别,但是......始终! 第二个示例- 行为符合预期。 链接至play.golang:https : //play.golang.org/p/INADVS3Ats 经过一番阅读,挖掘和实验后,我发
Spark shell:它基本上打开了scala spark sql:它似乎直接连接到hive元存储,我们可以用类似于hive的方式编写查询。并查询配置单元中的现有数据 我想知道这两者的区别。。在spark sql中处理任何查询是否与在spark shell中相同?我的意思是,我们可以在spark sql中利用spark的性能优势吗? Spark 1.5.2在这里。
根据你使用 Jekyll 的不同方式,Jekyll 允许你安装一些可选的附加功能。 数学支持 使用 Kramdown 时可以选择使用由 MathJax 提供的 LaTeX 格式到 PNG 格式的数学区块渲染器。具体细节可查阅 Kramdown 文档中的 math blocks (数学区块) 以及 math support (数学支持) 部分。 使用 MathJax 需要你设置引用相关的 JavaS
问题内容: (用Python shell编写) 为什么不允许对象向其添加属性? 问题答案: 请注意,实例没有属性: 一个在派生类中说明此行为的示例: 引用以下文档: […]声明采用一系列实例变量,并在每个实例中仅保留足够的空间来为每个变量保存一个值。因为未为每个实例创建空间,所以节省了空间。 编辑:要从评论中回答ThomasH,OP的测试类是“旧式”类。尝试: 您会注意到有一个实例。对象类可能没有