性能下降循环与迭代器

时间:2018-02-20 20:59:28

标签: performance loops kotlin

我正在将kotlin与lwjgl结合使用。到目前为止,我有以下代码每秒运行几千次:

library(ggmap)    
library(maptools)    
library(maps)    
library(ggplot2)    
library(fiftystater)    
library(reshape2)    

data("fifty_states")

map_stats <- read.csv(file.choose())    
ggplot(map_stats, aes(fill = statename, map_id = state)) +    
  geom_map(map = fifty_states) +    
  expand_limits(x = fifty_states$long, y = fifty_states$lat) +    
  coord_map() +    
  theme(legend.position = "bottom",    
        panel.background = element_blank()) 

因此,虽然它运行速度非常快,几乎消耗了我的帧时间,因此我不得不更换它,因为它在每个调用中都创建了// val textureMap = HashMap<Int, Texture>() fun bind() { var index = 0 for(entry in textureMap) { glActiveTexture(GL_TEXTURE0 + index) entry.value.bind() program.setInt(entry.key, index) ++index } } ,最终导致成千上万的这些对象最终变得垃圾收集并暂停我的程序几毫秒,这当然在我的应用程序中无法使用。

所以我继续将其更改为以下代码:

Iterator

由于某种原因,我注意到性能大幅下降,即现在每帧使用几秒钟的功能。使用// textures = ArrayList<Texture>() // indices = ArrayList<Int>() fun bind() { var index = 0 while(index < textures.size) { val uniform = indices[index] val texture = textures[index] glActiveTexture(GL_TEXTURE0 + index) texture.bind() program.setInt(uniform, index) ++index } } 我能够确定所有时间都花在jvisualvm本机部分以及glActiveTexture中的本机函数中。我绝对难以理解为什么会这样,特别是在比较两者的字节代码之后。

这是第一个(快速)版本的反编译类文件:

program.setInt(...)

这是慢速版本的字节代码:

public final void bind()
{
  int index = 0;
  Map localMap = (Map)this.textureMap;
  for (Map.Entry entry : localMap.entrySet())
  {
    GL13.glActiveTexture(33984 + index);
    ((Texture)entry.getValue()).bind(); Program 
      tmp66_63 = this.program;
    if (tmp66_63 == null) {
      Intrinsics.throwUninitializedPropertyAccessException("program");
    }
    tmp66_63.setInt(((Number)entry.getKey()).intValue(), index);
    index++;
  }
}

我非常困惑这里发生了什么。在这两个版本中,对public final void bind() { int index = 0; while (index < this.textures.size()) { Integer uniform = (Integer)this.indices.get(index); Texture texture = (Texture)this.textures.get(index); GL13.glActiveTexture(33984 + index); texture.bind(); Program tmp52_49 = this.program; if (tmp52_49 == null) { Intrinsics.throwUninitializedPropertyAccessException("program"); } Integer tmp62_61 = uniform;Intrinsics.checkExpressionValueIsNotNull(tmp62_61, "uniform");tmp52_49.setInt(tmp62_61.intValue(), index); index++; } } 的调用都是glActiveTexture,但其中一个需要花费更多时间。

有没有人知道我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

基本上我的整个问题都可以删除。我应该调试,而不仅仅是分析。问题是填充列表的代码,它没有删除旧的值,因此列表变得越来越大,循环随着时间的推移运行了很多次......

如果有人想知道我是如何通过分配修复我的问题,我基本上创建了两个集合,一个是包含制服,一个是将它们映射到纹理。然后我可以遍历制服然后获得相应的纹理。因此,没有创建无意义的迭代器对象,但我也没有任何重复:)