4

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

不幸的是,一旦代理人数过多,该计划就会大大减慢。

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

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();
    }
}
4

2 回答 2

3

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

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

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

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

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

  5. 你使用并发吗?如果您以并行方式运行算法,它可能会加快速度。

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

我希望这会有所帮助。

于 2015-07-16T22:04:09.010 回答
0

I had exactly the same problem. It may seem to be elegant to use this apache-commons builder however the compareTo method can be called a lot and when you have a lot of data it will be called even more. The objects are pretty light but there are so many generated in the short amount of time that it causes a big GC pressure and bigger pauses eventually giving an impression that the service is stale.

I wanted to come with something that is both reusable and does not allocate any memory and replaced the CompareToBuilder with the following util:

/**
 * 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() {}
}

the usage is as follows:

@Override
public int compareTo(Name o) {
    return compare(super.compareTo(o), this.english, o.english, this.arabic, o.arabic);
}
于 2020-03-05T10:09:43.610 回答