我正在建立一个有许多自治代理的模型。他们决定在他们的直接环境或“邻里”中选择哪个目标。他们这样做是为了检索对象,将它们添加到列表中,根据首选项对列表进行排序,并在每次迭代中选择首选项。这个决定决定了他们的行动。
不幸的是,一旦特工人数过多,该计划就会大幅放缓。
我使用比较方法(下图),它相对较短,但使用大量内存来比较对象。我想知道你们是否知道任何其他方法可能在计算上更有效?
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();
}
}
我遇到了完全相同的问题。使用这个apache-Commons构建器似乎很优雅,但是compareTo
方法可以调用很多,当您有很多数据时,它会被调用更多。对象很轻,但在很短的时间内生成了很多,这会导致巨大的GC压力和更大的暂停,最终给人一种服务过时的印象。
我想要一个既可重用又不分配任何内存的东西,并用以下util替换了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);
}
一些可能有用的要点(请注意,我没有使用repast simphony
,因此其中一些要点可能已经由该框架实现):
>
衡量标准——比较/分类是瓶颈吗?你说它使用了大量内存——这不会自动使程序运行变慢(可能存在GC开销问题吗?用VM args进行实验)。当然,在测量之前——预热JVM(以便JIT能够赶上代码的正常操作条件,等等)。了解jvisualvm
的情况。
我不知道您要传递给append
方法的对象是什么,但考虑到您可能比现在这样比较对象更快返回的情况。尝试使用特定域模型的知识。
您说过,代理“检索对象,将其添加到列表”并进行排序。也许存储已经排序的邻居列表会有好处,如果有什么变化(这是一个猜测),列表中可能会有一些变化——所以它几乎是完全排序的。使用能够快速处理“几乎排序的列表”列表的排序算法,并将结果与默认的Java排序算法进行比较。当然,这取决于你的邻居模式改变的频率。如果您的模型不会改变(我认为类型
不会改变),那么排序问题将不存在。
考虑使用普通Java代码来CompareToBuilder
——如果有数百万个对象,那么对象创建可能会带来很大的开销(如果它位于关键路径/瓶颈上)。
你利用并发吗?如果你以并行方式运行你的算法,它可能会加速。
许多其他优化取决于您特定的对象结构和关系。例如,您将Tree
作为泛型中的类型-也许这棵树没有平衡,也许您可以使用AVL
,Heap
,或将LinkedList
更改为ArrayList
等。实验
我希望这会有所帮助。
我在一本书中读到,Repast Simphony中的投影可以是投影界面的任何用户实现。我想创建一个自定义投影,但它看起来比我预期的更复杂。你们有没有人尝试过创建自己的投影?如果是的话,你能解释一下如何进行吗?非常感谢。
我已经编写了Java代码,需要与Repast Simphony集成。 但是当我试图为reover Simphony设置与我的代码相同的工作空间时,我遇到了这个错误: 语法错误,注释仅在源代码级别为1.5或更高时可用 有什么建议吗?
我想用java信号量解决用餐哲学家的问题,但我被卡住了。最高ID的筷子应该是可用的,但它似乎总是采取,我不知道为什么。谁能告诉我我错在哪里了? Fork类: 哲学家班: 主要内容:
我有一个名为truck的代理,它将执行一些操作(例如装载包裹)。这里的问题与执行动作的代理的随机序列有关。例如,假设我有三辆卡车,装载顺序是随机的。 如何确保代理(卡车)根据顺序执行操作,例如通过其id,以便我们始终可以从模拟中获得一致的结果。
问题内容: 我正在尝试处理Java中正确的内存使用和垃圾回收。无论如何,我都不是新手程序员,但是在我看来,一旦Java接触到一些内存,它就永远不会被释放供其他应用程序使用。在这种情况下,您必须确保 峰值内存 永远不会太高,否则应用程序将继续使用峰值内存使用率。 我编写了一个小示例程序试图证明这一点。它基本上有4个按钮… 用大约25,000,000个长字符串项目填充类范围变量。 呼叫 重新分配列表-
问题内容: 我的磁盘上只有168MB的文件。这只是一个逗号分隔的单词,id的列表。该单词的长度可以为1-5个字符。有650万行。 我在python中创建了一个字典,将其加载到内存中,因此我可以针对该单词列表搜索传入的文本。当python将其加载到内存中时,它显示已使用的1.3 GB RAM空间。知道为什么吗? 假设我的word文件如下所示… 然后再加上650万。然后,我遍历该文件并创建一个字典(p