Java String比较过程

时间:2015-05-11 10:15:27

标签: java string performance if-statement switch-statement

我关心的是,java如何比较String以及它是如何优化的。

让我们考虑我需要比较用户提供的字符串,在我的代码中使用10个字符串。在这10个字符串中,5个以'A'开头,其他5个以'B'开头。

现在如果我写if..elseif..switch,那么每个字符串将被比较,直到它与任何字符串匹配,并且在最坏的情况下,其中任何一个字符串在第9或第10个条件下匹配或一点也不。因此,每个输入执行平均8到10个条件。

现在我的问题是我们可以通过在检查具有实际值的输入字符串之前再添加一个条件(一种过滤器)来优化这种情况。如下所示,

   if(inputString.charAt(0) == 'A'){
            if(){
                ....
            }else if(){
                ....
            }
        }else if(inputString.charAt(0) == 'B'){
            if(){
                ...
            }else if(){
                ...
            }
        }

它是否可以提高系统的性能,或者Java已经针对这种情况进行了内部优化。

3 个答案:

答案 0 :(得分:1)

if语句

讨论通常围绕复杂的if语句开始:

if (value == 0){
    return result0;
} else if (value == 1){
    return result1;
} else if (value == 2){
    return result2;
} else if (value == 3){
    return result3;
} else if (value == 4){
    return result4;
} else if (value == 5){
    return result5;
} else if (value == 6){
    return result6;
} else if (value == 7){
    return result7;
} else if (value == 8){
    return result8;
} else if (value == 9){
    return result9;
} else {
    return result10;
}

通常,这种类型的构造不受欢迎。主要问题是执行流程越深入,必须评估的条件越多。当值为9时,完成执行将花费更长时间,因为必须事先评估每个其他条件,因此值必须为0。随着条件总数的增加,深入到条件的性能也会增加。虽然不建议使用大量if条件,但您可以采取一些步骤来提高整体性能。

第一步是按频率降序排列条件。由于在第一个条件之后退出是最快的操作,因此您需要确保尽可能多地进行操作。假设前一个例子中最常见的情况是值等于5,第二个最常见的是值等于9.在这种情况下,你知道在得到最常见的情况之前将评估五个条件而在到达之前要评估九个条件。第二种最常见的情况;这非常低效。尽管条件的数字顺序越来越容易阅读,但实际上应该按如下方式重写:

if (value == 5){

    return result5;
} else if (value == 9){
    return result9;
} else if (value == 0){
    return result0;
} else if (value == 1){
    return result1;
} else if (value == 2){
    return result2;
} else if (value == 3){
    return result3;
} else if (value == 4){
    return result4;
} else if (value == 6){
    return result6;
} else if (value == 7){
    return result7;
} else if (value == 8){
    return result8;
} else {
    return result10;
}

现在,两个最常见的条件出现在if语句的顶部,确保这些情况的最佳性能。

优化if语句的另一种方法是将条件组织成一系列分支,遵循二进制搜索算法来查找有效条件。在可能存在大量条件并且没有一个或两个将以足够高的速率发生以根据频率简单地排序的情况下,这是可取的。目标是尽可能减少要评估的条件数量。如果示例中的所有值条件都以相同的相对频率发生,则if语句可以重写如下:

if (value < 6){

    if (value < 3){
        if (value == 0){
            return result0;
        } else if (value == 1){
            return result1;
        } else {
            return result2;
        }
    } else {
        if (value == 3){
            return result3;
        } else if (value == 4){
            return result4;
        } else {
            return result5;
        }
    }

} else {

    if (value < 8){
        if (value == 6){
            return result6;
        } else {
            return result7;
        }
    } else {
        if (value == 8){
            return result8;
        } else if (value == 9){
            return result9;
        } else {
            return result10;
        }

    }
}

此代码确保不会评估任何超过四个条件。不是评估每个条件以找到正确的值,而是在识别实际值之前将条件首先分成一系列范围。此示例的整体性能得到改善,因为已删除了需要评估八个和九个条件的情况。条件评估的最大数量现在为4,从而比以前版本的执行时间平均节省约30%。还要记住,else语句没有条件可以评估。然而,问题仍然是每个附加条件最终花费更多时间来执行,不仅影响性能而且影响该代码的可维护性。这是switch语句的用武之地。

切换声明

switch语句简化了多个条件的外观和性能。您可以使用switch语句重写上一个示例,如下所示:

switch(value){
    case 0:
        return result0;
    case 1:
        return result1;
    case 2:
        return result2;
    case 3:
        return result3;
    case 4:
        return result4;
    case 5:
        return result5;
    case 6:
        return result6;
    case 7:
        return result7;
    case 8:
        return result8;
    case 9:
        return result9;
    default:
        return result10;
}

此代码清楚地表明条件以及返回值,可以说是更易读的形式。 switch语句具有允许直通条件的额外好处,允许您为许多不同的值指定相同的结果,而不会创建复杂的嵌套条件。 switch语句经常被其他编程语言引用为评估多个条件的最佳选择。这不是因为switch语句的性质,而是因为编译器如何能够优化switch语句以便更快地进行评估。

另一个选项:数组查找

在JavaScript中处理条件有两种以上的解决方案。除了if语句和switch语句之外还有第三种方法:在数组中查找值

for(String s: arr){
    if(s.equals(targetValue))
        return true;
}
return false;

尽管数组查找时间也会增加您所使用的数组的深度,但增量增量非常小,以至于它与if和switch语句的每个条件评估的增加无关。这样,只要满足大量条件,阵列查找就是理想的,条件可以用数字或字符串等离散值表示

最快的条件

这里介绍的三种技术 - if语句,switch语句和数组查找 - 各自用于优化代码执行:

•在以下情况下使用if语句:

  • 要测试的离散值不超过两个。
  • 有很多值可以很容易地分成范围。

•在以下情况下使用switch语句:

  • 有两个以上但少于10个离散值 测试。
  • 条件没有范围,因为值是非线性的。

•在以下情况下使用数组查找:

  • 要测试的值超过10个。
  • 条件的结果是单个值而不是数字 要采取的行动。

答案 1 :(得分:0)

您可以使用Map或Set中的查找,而不是循环遍历每个值。

答案 2 :(得分:0)

Java逐字符比较字符串。 通过“优化”,您每次都会比较需要多一个字符。 您开始比较第一个字符(A或B),然后是整个单词,再次包括第一个字符。

你的解决方案很好,因为减少了整个单词的比较数量。 如果你把单词分成2个部分(第一个字母和单词的其余部分),你可以比较开头的第一个字符,就像你正在做的那样......然后是另一部分。 问题是你可能会花费更多的时间来切片而不是比较....所以检查它;)

还有一件事......如果你使用一个开关,花在搜索上的时间并不取决于元素的数量......所以如果你使用一个开关就不需要第一次优化。

你也可以让全局HashMap在里面找到你的字符串......所以避免了交换机的“地图创建”......