【问题标题】:Calling many methods of many objects many times per second每秒多次调用许多对象的许多方法
【发布时间】:2015-08-05 00:44:47
【问题描述】:

我有这样的结构

  abstract Class Entity {
    //some variables... 
    //some methods ...
    public abstract void render(Graphics g);
    }

那是父母..现在我有 3 个孩子..

Class A extends Entity{}
Class B extends Entity{}
Class C extends Entity{} 

每个类都有一些不同的渲染内容。一个是例如绘制黄色圆圈,第二个是绿色文本,第三个是显示图像。

但是……有一件事。

Class A have List<B>... 
Class B have List<C>... 

例如,一个实体有 10 个 B...每个 B 有 20 个 C...所以现在..我有一个渲染方法,每秒渲染 60x.. 而且我必须从每个对象调用每个渲染方法。

所以我有这样的东西

for(A a : listOfAs){
   for(B b : listOfBs){
      for(C c : listOfCs){
         c.render(g);
      }b.render(g);
   }a.render(g);
}

现在,如果您想象我有更多这样的对象,并且我将此方法称为每秒 60 次……我发现这真的……非常糟糕的做法……我不知道如何更好地解决这个问题。 ..我不认为这对于每个循环实际上是最好的解决方案。有人有什么想法吗?

我正在考虑这样实现孩子:

Entity x = new A(); ... 
Entity y = new B(); ... 

等等,但是有些类有其他方法必须像这样循环,我不能从父级调用它们。

对于渲染方法...只要坚持一个事实,你必须在很长一段时间内在短时间内循环多次。

我无法通过这个...我被困在这里很长一段时间,我不知道如何解决这个问题。

【问题讨论】:

  • 我觉得 Lambda 在这里循环会更快,因为嵌套的 foreach 循环将发生 listOfAs.count * listOfBs.count * listOfCs.count 次,而 lambda 使用某种形式的 hashjoin 或内部正确完成加入可以做到listOfAs.count + listOfBs.count + listOfCs.count 次。我会写它的证明,但这不会回答你的问题。
  • 这听起来像是首先将您的实体渲染为临时图像,然后在paint/paintComponent中绘制它的情况......而且,您真的不需要每秒渲染60倍;眼睛只有大约 24 倍的效果
  • @Adam 我不确定你指的是什么,但恐怕如果没有一个好的解释,我不相信!有许多对象需要迭代;没有多少加入可以减少这个数字,当然?我的直觉是考虑利用并发性。另一个优化可能是确定哪些像素将被重绘并仅绘制最后一个值,尽管这样做的成本最终可能会超过收益。
  • 您是否需要一直重新渲染它们?一个经典的解决方案是跟踪真正发生变化的内容并仅重新渲染。
  • 您确定 A、B 和 C 相关吗?或者他们是依赖关系?

标签: java for-loop game-engine


【解决方案1】:

由于您的主要关注点似乎是渲染或不渲染某些实体,无论它们是否是子实体,您都应该对通用图形编程优化和技巧以及渲染引擎如何提高性能进行一些研究。渲染引擎性能的一大提升就是不做不必要的工作。

已经提到了一个,即确定哪些实际改变了状态并只渲染它们。另一种方法是根据图形画布上每个实体的边界检查视图的边界,并仅渲染边界内的内容。无论您有 2D 还是 3D,您都可能有重叠的东西,因此您可以确定哪些实体被遮挡并避免渲染它们。如果您的子实体在父实体的范围内,那么您可以避免渲染对象图的整个树并避免许多元素的迭代。

此外,这些事情可以通过检查必须重新渲染的实体的一部分、未被遮挡的部分等来部分完成。这可能需要对您的 API 进行一些更改以传递实体所在的边界预计会为每个项目呈现而不是整个图形上下文。

如果您对任何可渲染实体(例如脏状态或边界)一无所知,那么您将被困在对它们全部进行迭代并分别调用渲染一个。

【讨论】:

    【解决方案2】:

    我不确定我是否完全遵循...但是您是否正在制作一个由其他几个实体组成的实体?不管你怎么想,你总是必须访问每个实体一次。选择哪种循环并不重要。

    但是,如果您有一个由一堆精灵组成的实体,我建议您创建一个新纹理并将这些精灵渲染到该纹理上一次。然后你只需要在每一帧渲染那个纹理。说得通?

    【讨论】:

      【解决方案3】:

      我找到了一位工作的朋友,他看了看并帮助我稳定了它。谢谢大家的提示和帮助。我不认为 lambda 在这里有很大帮助。

      很难解释我在这个项目中所做的事情。这根本不是游戏.. 这是不同的东西。我得到了双重渲染,所以它真的是每秒 2 * 30 次。我只是在玩我以后可以在我的引擎中实际使用的对象负载。但是这个问题让我卡了很长一段时间。

      再次。谢谢大家。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-16
        • 2020-11-30
        • 1970-01-01
        • 2021-03-13
        • 1970-01-01
        相关资源
        最近更新 更多