Java 创建新集合太慢

发布于 2024-08-26 12:02:06 字数 420 浏览 3 评论 0原文

我有这个程序,它有一些类似于以下的递归函数:

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

我正在做的是将每个集合与集合 s 结合起来。并在每个联合上运行 lambda。 我运行探查器,发现 c.clone() 操作占用了我代码 100% 的时间。有什么办法可以大大加快这个速度吗?

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. And run lambda on each one of the union.
I run a profiler and found the c.clone() operation took 100% of the time of my code. Are there any way to speed this up considerably?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陪你到最终 2024-09-02 12:02:06

当你克隆时,你真正想要做什么,也许你不需要做一个完整的克隆?

提高 lambda 函数性能的最佳选择是扩展 HashSet 并使用特定于您的情况的自定义定义覆盖克隆定义...

不幸的是,我不知道有任何其他方法可以真正帮助您提供更多信息。

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...

I don't know of anyother way to really help with out more information unfortunatly.

泅渡 2024-09-02 12:02:06

如果我做对了,你可以尝试执行以下操作:

lambda(Set p) {
    lambda(p + further elements);
}

你可以通过重新实现列表并使用节点作为 lambda 的参数来避免克隆 p 例如:

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
}

这是一个低级解决方案,你必须实现缓慢的顺序搜索/ find-algorithm(如果您依赖于集合中的唯一元素),但根据我的经验,这样的堆栈对于大多数递归算法来说是一个很好的解决方案。

If I get it right you try to do the following:

lambda(Set p) {
    lambda(p + further elements);
}

You can avoid cloning p e.g. by reimplementing a list and using the Nodes as parameters for 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.

南街九尾狐 2024-09-02 12:02:06

这就是我为了加快一切速度所做的事情,这样我就不必创建新的集合。

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

平均而言,这要快得多,并且程序在 addAll 和 removeAll 上花费的时间大致相同。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文