gpt4 book ai didi

java - 这种对象的使用是否多余和/或效率低下?

转载 作者:行者123 更新时间:2023-12-01 07:17:18 25 4
gpt4 key购买 nike

我对使用对象相当缺乏经验,所以我真的很想要一些输入。

我正在尝试从包含某些“不需要的单词”的列表中删除评论,评论和“不需要的单词”列表都在 ArrayList 对象中。

这是一个名为 FormHelper 的类的内部,该类包含私有(private)成员 comments 作为 ArrayList,auditList ArrayList 是在本地创建的一个名为 populateComments() 的成员函数,然后调用此函数(如下)。 PopulateComments() 由构造函数调用,因此该函数仅在创建 FormHelper 实例时调用一次。

private void filterComments(ArrayList <String> auditList) {
for(String badWord : auditList) {
for (String thisComment : this.comments) {
if(thisComment.contains(badWord)) {
int index = this.comments.indexOf(thisComment);
this.comments.remove(index);
}
}
}
}

我的实现方式感觉不太对劲,我还担心我使用 ArrayList 函数的效率低下。我的怀疑正确吗?

最佳答案

效率不是特别高。然而,找到更有效的解决方案并不简单。

让我们回到一个更简单的问题。

private void findBadWords(List <String> wordList, List <String> auditList) {
for(String badWord : auditList) {
for (String word : wordList) {
if (word.equals(badWord)) {
System.err.println("Found a bad word");
}
}
}
}

假设wordList包含N个单词,auditList包含M个单词。一些简单的分析将表明内部循环被执行了N x M次。 N 因素是不可避免的,但 M 因素却令人不安。这意味着您要检查的“坏”词越多,检查所需的时间就越长。

有一个更好的方法来做到这一点:

private void findBadWords(List <String> wordList, HashSet<String> auditWords) {
for (String word : wordList) {
if (auditWords.contains(word))) {
System.err.println("Found a bad word");
}
}
}

为什么这样更好?它更好(更快),因为 HashSet::contains 不需要一次检查所有审核词。事实上,在最佳情况下,它不会检查其中任何一个(!),而平均情况下只会检查其中一两个。 (我不会详细说明原因,但如果您想了解,请阅读有关哈希表的维基百科页面。)

<小时/>

但是你的问题更复杂。您正在使用 String::contains 来测试每个评论是否包含每个坏词。这不是一个简单的字符串相等测试(根据我的简化版本)。

要做什么?

一个潜在的解决方案是将评论拆分为单词数组(例如使用 String::split 然后使用 HashSet 查找方法。但是:

  • 这会改变代码的行为。 (实际上,这是一种很好的方式:阅读Scunthorpe problem!)您现在只会匹配审核单词,因为它们是评论文本中的实际单词。

  • 将字符串拆分为单词并不便宜。如果您使用 String::split ,则需要创建并使用 Pattern 对象来查找单词边界,为每个单词创建子字符串并将它们放入数组中。您可能可以做得更好,但这始终是一个不平凡的计算。

所以真正的问题是优化是否会带来返回。这最终取决于 M 的值;即您正在寻找的坏词数量。 M 越大,就越有可能将评论拆分成单词并使用 HashSet 来测试单词。

另一种可能的解决方案不涉及拆分评论。您可以获取审核单词列表并将它们组装成单个正则表达式,如下所示:\b(word-1|word-2|...|word-n)\b。然后将此正则表达式与 Matcher::find 结合使用来搜索每个评论字符串中的不良单词。性能将取决于 Java 平台中正则表达式引擎的优化能力。它有可能比 split 更快。

<小时/>

我的建议是在开始之前对整个应用程序进行基准测试和分析。仅优化:

  1. 当基准测试表明进行此评论检查的请求的总体性能令人担忧时。 (如果没问题,就不要浪费时间优化。)

  2. 当分析表明方法是性能热点时。 (真正的热点很可能在其他地方。如果是这样,您应该优化它们而不是此方法。)

请注意,在您考虑优化之前,我们假设您已经(充分)完成了您的应用程序并为其创建了一个现实的基准。 (过早优化是一个坏主意......除非您真的知道自己在做什么。)

关于java - 这种对象的使用是否多余和/或效率低下?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56411332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com