由于递归使用导致的性能问题

时间:2017-04-18 20:32:14

标签: java

我在执行下面的代码时出现性能问题。它使用递归函数。现在,运行它需要10670毫秒。有人可以帮我改进吗?我正在使用java 8,但由于我还不熟悉它,我没有用java 8实现它。我在线红色,它说java 8可以提高性能,但也可以根据你操作的数据量来提高性能。谢谢大家

public static void RemoveDuplicateData(List<VariableDataGroup> variableDataGroups) {
        if (variableDataGroups == null) {
            return;
        }
        for (VariableDataGroup varDataGroup : variableDataGroups) {
            RemoveDuplicateData(varDataGroup.getOrDataList());
            if (varDataGroup.getAndDataList() != null) {
                removeAnyDuplicateAndBlankCodesFromAndDataList(varDataGroup);
            }

            if (varDataGroup.getNotDataList() != null) {
                removeAnyDuplicateAndBlankCodesFromNotDataList(varDataGroup);
            }
        }
    }

    private static void removeAnyDuplicateAndBlankCodesFromAndDataList(VariableDataGroup varDataGroup) {
        for (int x = (varDataGroup.getAndDataList().size()-1) ; x >= 0; x--) {
            if (varDataGroup.getAndDataList().get(x) == null || varDataGroup.getAndDataList().get(x).isEmpty())
            {
                varDataGroup.getAndDataList().remove(x);
            } else {
                for (int y = 0; y < x; y++) {
                    if (varDataGroup.getAndDataList().get(x).equals(varDataGroup.getAndDataList().get(y))) {
                        varDataGroup.getAndDataList().remove(x);
                        break;
                    }
                }
            }
        }
    }

    private static void removeAnyDuplicateAndBlankCodesFromNotDataList(VariableDataGroup varDataGroup) {
        for (int x = (varDataGroup.getNotDataList().size()-1) ; x >= 0; x--) {
            if (varDataGroup.getNotDataList().get(x) == null    || varDataGroup.getNotDataList().get(x).isEmpty())
            {
                varDataGroup.getNotDataList().remove(x);
            } else {
                for (int y = 0; y < x; y++) {
                    if (varDataGroup.getNotDataList().get(x).equals(varDataGroup.getNotDataList().get(y))) {
                        varDataGroup.getNotDataList().remove(x);
                        break;
                    }
                }
            }
        }
    }

    public class VariableDataGroup {    
        private String appearingData = "";
        private boolean dataFound ;
        private List<String> notDataList = new ArrayList();
        private List<String> andDataList = new ArrayList();
        private List<VariableGroup> orDataList = new ArrayList();
        ...
    } 

感谢Andy Turner和大家的帮助和建议。这是我当时做的。

private static void removeDuplicateAndEmptyData(VariableDataGroup varDataGroup) {
        Set<String> dedupedAndDataSet = new LinkedHashSet<>();
        List<String> andDataList = varDataGroup.getAndDataList();
        Set<String> dedupedNotDataSet = new LinkedHashSet<>();
        List<String> notDataList = varDataGroup.getNotDataList();

        for (String s : andDataList) {
          if (s != null && !s.isEmpty()) {
            dedupedAndDataSet.add(s);
          }
        }
        andDataList.clear();
        andDataList.addAll(dedupedAndDataSet);

        for (String s : notDataList) {
          if (s != null && !s.isEmpty()) {
            dedupedNotDataSet.add(s);
          }
        }
        notDataList.clear();
        notDataList.addAll(dedupedNotDataSet);
    }

    public static void RemoveDuplicateData(List<VariableDataGroup> variableDataGroups) {
        if (variableDataGroups == null) {
            return;
        }
        for (VariableDataGroup varDataGroup : variableDataGroups) {
            RemoveDuplicateData(varDataGroup.getOrDataList());
            if (varDataGroup.getAndDataList() != null) {
                removeDuplicateAndEmptyData(varDataGroup);
            }

            if (varDataGroup.getNotDataList() != null) {
                removeDuplicateAndEmptyData(varDataGroup);
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

正如我上面评论的那样,很难提供很多帮助,因为我们对您正在处理的数据量一无所知。

但是,您可以使用Set而不是List来进行重复数据删除。

例如,您的removeAnyDuplicateAndBlankCodesFromAndDataList可以这样写:

private static void removeAnyDuplicateAndBlankCodesFromAndDataList(VariableDataGroup varDataGroup) {

    List<String> list = varDataGroup.getAndDataList();

    // Copy the list into the set - this removes duplicates.
    Set<String> deduped = new LinkedHashSet<>(list);
    // Remove the null and empty string, if they are present.
    deduped.remove("");
    deduped.remove(null);

    // Replace the list contents with those of deduped.
    list.clear();
    list.addAll(deduped);
}

这比使用List的工作少得多:Set s自动不包含重复项,并且从ArrayList重复删除单个元素的效率非常低(除非它在结束)。

请注意,// Copy the list into the set评论向下的所有内容都适用于“某些列表” - 因此您无需为not列表复制此方法,您只需更改方法即可接受list作为参数:

private static void removeDuplicates(List<String> list) {
  // ...
}

然后像这样调用:

if (varDataGroup.getAndDataList() != null) {
  removeDuplicates(varDataGroup.getAndDataList());
}
if (varDataGroup.getNotDataList() != null) {
  removeDuplicates(varDataGroup.getNotDataList());
}

(你甚至可以将空检查移到方法中,以避免重复)。

当然,您也可以首先将andDataList声明为Set,然后您不必担心重复项(尽管您必须以某种方式过滤空值和空字符串)。

private Set<String> andDataList = new LinkedHashSet<>();