[英]Java creation of new set too slow
I have this program where it have some recursive function similar to this: 我在这个程序中有一些类似于此的递归函数:
public static void lambda(HashSet<Integer> s){
if(end(s)){
return;
}
for(int i=0;i<w;i++){
HashSet<Integer> p = (HashSet) s.clone();
p.addAll(get_next_set());
do_stuff_to(p);
lambda(p);
}
}
What I'm doing is union every set with the set s. 我正在做的是将每个集合与集合s合并。 And run lambda on each one of the union. 并在每个联盟上运行lambda。 I run a profiler and found the c.clone() operation took 100% of the time of my code. 我运行了探查器,发现c.clone()操作花费了我100%的代码时间。 Are there any way to speed this up considerably? 有什么办法可以大大加快速度吗?
When you are cloning, what are you really trying to do, maybe you don't need to do a complete cloan? 克隆时,您真正要做什么,也许您不需要完全克隆。
Your best bet at improving the performance of your lambda function is to extend HashSet and overide the clone definition with a custom one that is particular to your situation... 改善lambda函数性能的最佳选择是扩展HashSet并使用特定于您的情况的自定义项覆盖克隆定义...
I don't know of anyother way to really help with out more information unfortunatly. 我不知道有什么其他方法可以真正帮助您获得更多信息。
If I get it right you try to do the following: 如果我做对了,您可以尝试执行以下操作:
lambda(Set p) {
lambda(p + further elements);
}
You can avoid cloning p eg by reimplementing a list and using the Nodes as parameters for lambda: 您可以避免克隆p,例如通过重新实现列表并将Nodes作为lambda的参数:
class Node {
int content;
Node next;
Node(int content, Node next) {
this.content = content;
this.next = next;
}
}
void lambda(Node set) {
// add new elements to front
Node newSet = set;
for(Integer i : new_elements() ) {
newSet = new Node(i, newSet);
}
lambda(newSet);
// Observe that set is not modified by adding new elements
}
This is a low-level-solution and you would have to implement a slow sequential search/find-algorithm (if you rely on unique elements in the set), yet in my experience such a stack is a good solution for most recursive algorithms. 这是一个低级解决方案,您将必须实现缓慢的顺序搜索/查找算法(如果您依赖于集合中的唯一元素),但是以我的经验,这样的堆栈对于大多数递归算法而言都是不错的解决方案。
This is what I did to speed up everything, this way I never have to create new sets. 这是我加快所有工作的方法,因此不必创建新的集合。
public static void lambda(HashSet<Integer> s){
if(end(s)){
return;
}
ArrayList<Integer> diff = new ArrayList<Integer>();
for(int i=0;i<w;i++){
//an array version of the next set, it is pre-computed
int[] a = get_next_set_array();
for(int j=0;j<a.length;j++){
if(!s.contains(a[j])){
diff.add(a[j]);
}
}
s.addAll(diff);
do_stuff_to(s);
s.removeAll(diff);
diff.clear();
lambda(p);
}
}
On average this is much faster, and the program spend roughly the same amount of time on the addAll and removeAll. 平均而言,这要快得多,并且程序在addAll和removeAll上花费的时间大致相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.