【问题标题】:Agent decision making in repast simphony using java uses a lot of memory使用 java 进行就餐 simphony 中的代理决策会占用大量内存
【发布时间】:2015-07-16 21:27:59
【问题描述】:

我正在构建一个包含多个自主代理的模型。他们决定在他们的直接环境或“邻居”中选择哪个对象。他们这样做是为了检索对象,将它们添加到列表中,根据偏好对列表进行排序,然后选择每次迭代的最佳选择。决定决定了他们的行动。

不幸的是,一旦代理人数过多,程序就会大大减慢。

我使用比较方法(如下)来比较对象,该方法相对较短,但占用大量内存。我想知道你们是否知道其他任何计算效率更高的方法?

class ObjectComparator implements Comparator <Tree> {

    @Override
    public int compare(Object object1, Object object2) {
        return new CompareToBuilder()
            .append(object1.getTYPE(), object2.getTYPE())
            .append(object2.getDBH(), object1.getDBH())
            .append(object1.getDistanceFrom(), object2.getDistanceFrom())
            .append(object2.isIdeal(), tree1.isIdeal()).toComparison();
    }
}

【问题讨论】:

    标签: java agent-based-modeling repast-simphony


    【解决方案1】:

    一些可能有用的点(注意我没有使用repast-simphony所以有些点可能已经被这个框架实现了):

    1. 衡量 - 比较/排序瓶颈?您说它使用了大量内存 - 这不会自动使程序运行速度变慢(可能存在 GC 开销问题吗?尝试使用 VM args)。当然,在测量之前 - 预热 JVM(以便 JIT 可以赶上您的代码的正常操作条件等)。了解jvisualvm 发生了什么。

    2. 我不知道您传递给append 方法的对象是什么,但考虑一下您可能会比现在比较对象更快地返回的情况。尝试使用特定领域模型的知识。

    3. 您说过代理“检索对象,将它们添加到列表中”并进行排序。也许存储已经排序的邻居列表是有益的,如果某些事情可能会发生变化(这是一个猜测),列表中会有一些变化 - 所以它几乎是完全排序的。使用能够非常快速地处理“几乎已排序的列表”列表的排序算法,并将结果与​​默认的 Java 排序算法进行比较。当然,这取决于你的邻居模型多久改变一次。如果您的模型不会改变(我想TYPE 不会改变),那么排序问题将不存在。

    4. 考虑对CompareToBuilder 使用纯 Java 代码 - 如果您有数百万个对象,则创建对象可能是一个很大的开销(如果它位于关键路径/瓶颈上)。

      李>
    5. 您是否使用并发?如果您以并行方式运行算法,也许它会加快速度。

    许多其他优化取决于您的特定对象结构和关系。例如。你有 Tree 作为泛型中的类型 - 也许这棵树没有平衡,也许你可以使用 AVLHeap,或者将 LinkedList 更改为 ArrayList 等。实验和测量。

    我希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      我遇到了完全相同的问题。使用这个 apache-commons 构建器似乎很优雅,但是 compareTo 方法可以调用很多,当你有很多数据时,它会被调用更多。 这些对象很轻,但在短时间内生成了太多对象,这会导致巨大的 GC 压力和更大的停顿,最终给人一种服务陈旧的印象。

      我想提供既可重用又不分配任何内存的东西,并将CompareToBuilder 替换为以下实用程序:

      /**
       * Utility for implementing null safe and efficient {@link Comparable#compareTo(Object)}.
       *
       * Note: it does not use vararg for a performance reason.
       *
       * @author aleksanderlech
       */
      public final class ComparingUtils {
      
          public static <T1 extends Comparable<T1>, T2 extends Comparable<T2>, T3 extends Comparable<T3>> int compare(int upstreamComparision, T1 o1v1, T1 o2v1, T2 o1v2, T2 o2v2, T3 o1v3, T3 o2v3) {
              return compare(compare(compare(upstreamComparision, o1v1, o2v1), o1v2, o2v2), o1v3, o2v3);
          }
      
          public static <T1 extends Comparable<T1>, T2 extends Comparable<T2>> int compare(int upstreamComparision, T1 o1v1, T1 o2v1, T2 o1v2, T2 o2v2) {
              return compare(compare(upstreamComparision, o1v1, o2v1), o1v2, o2v2);
          }
      
          public static <T1 extends Comparable<T1>> int compare(int upstreamComparision, T1 v1, T1 v2) {
              if(upstreamComparision == 0) {
                  if(v1 == v2) {
                      return 0;
                  }
                  if(v1 == null) {
                      return 1;
                  } else if(v2 == null) {
                      return -1;
                  }
                  return v1.compareTo(v2);
      
              }
      
              return upstreamComparision;
          }
      
          private ComparingUtils() {}
      }
      

      用法如下:

      @Override
      public int compareTo(Name o) {
          return compare(super.compareTo(o), this.english, o.english, this.arabic, o.arabic);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-10
        • 2022-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-02
        相关资源
        最近更新 更多