代码之家  ›  专栏  ›  技术社区  ›  Chao Xu

Java新设置太慢

  •  0
  • Chao Xu  · 技术社区  · 14 年前

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

    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%时间。有什么办法可以大大加快速度吗?

    3 回复  |  直到 14 年前
        1
  •  0
  •   hhafez    14 年前

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

    要提高lambda函数的性能,最好的办法是扩展hashset,并使用一个特定于您的情况的自定义定义覆盖克隆定义…

    我不知道还有什么其他的方法可以帮你不幸地得到更多的信息。

        2
  •  0
  •   Searles    14 年前

    如果我做对了,你可以试着做以下事情:

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

    您可以避免克隆p,例如通过重新实现列表并将节点用作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
    }
    

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

        3
  •  0
  •   Chao Xu    14 年前

    这就是我所做的一切加速,这样我就永远不需要创造新的设置。

    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上花费的时间大致相同。