我正在用Java编写代码,根据string
是否以某些字符开头,而dataset
循环,dataset
预计会很大。
我想知道startsWith
是否比indexOf
更快。我确实试验了2000条记录,但没有发现任何差异。
答案 0 :(得分:9)
startsWith
只需要在字符串的最开头检查是否存在 - 它的工作量较少,因此应该更快。
我的猜测是你的2000条记录在几毫秒内完成(如果那样)。每当您想要将一种方法与另一种方法进行基准测试时,请尝试在足够的时间内进行,以使时间差异显着。我发现10-30秒足以显示出显着的改进,但足够短以使得可以多次运行测试。 (如果这是一次严肃的调查,我可能会尝试更长时间。我的大多数基准测试都是为了好玩。)
另外,请确保您拥有不同的数据 - indexOf
和startsWith
在indexOf
返回0 的情况下,的运行时间大致相同。因此,如果您的所有记录都与模式匹配,那么您实际上并未正确测试。 (我不知道你的测试当然是否属于这种情况 - 这只是需要注意的事项。)
答案 1 :(得分:7)
一般来说,微优化的黄金法则适用于此:
“测量,不要猜测”。
与此类型的所有优化一样,两个调用之间的差异几乎肯定无关紧要,除非您检查数百万个长度为数万个字符的字符串。
在您的代码上运行一个分析器,只有在您可以衡量它是否会降低您的速度时才会优化此调用。然后,使用更易读的选项(在这种情况下,startsWith)。一旦你知道这个区块正在减慢你的速度,那么试试两个并使用更快的速度。冲洗。重复; - )
在学术上,我的猜测是startsWith可能会使用indexOf来实现。检查源代码,看看你是否感兴趣。(事实证明,startsWith不会调用indexOf)
答案 2 :(得分:5)
即使没有查看来源,应该很清楚,至少对于大字符串和短模式,startsWith更快:
a.starts与(b)的运行时间绑定为b的长度。最多检查前两个字符后,搜索结束。
a.indexOf(b)的运行时间较长(取决于actual algorithm)。每个算法至少有一个运行时间,具体取决于a的长度。粗略地说,您可以说,您必须查看每个角色一次以检查该模式是否从该位置开始。
然而,与往常一样,如果您真的看到实践中的差异,则取决于实际用例。衡量现实生活中的差异从来都不错。
答案 3 :(得分:2)
可能,如果它不匹配,它可以停止查找,而indexOf需要在字符串中稍后查找出现。
答案 4 :(得分:1)
startsWith比indexOf == 0更清晰。
您是否将测试确定为您需要牺牲可读性的性能瓶颈?
答案 5 :(得分:0)
您提到数据集预计会很大。所以我敢打赌,很多性能将会访问这个数据集并在内存中处理它。这意味着使用一个或另一个不会改变性能显着。但是,如果这对您很重要,您可以编写自己的startWith方法,该方法可能比标准库方法快得多,或者至少您确切知道要做什么。
答案 6 :(得分:0)
不幸的是,statsWith无法正常工作!它在sene后面使用“ indexOf”(懒惰的开发人员:D),因此indexOf比已实现的statsWith快10倍。
答案 7 :(得分:-2)
public class Test
{
public static void main(String args[]) {
long value1 = System.currentTimeMillis();
for(long i=0;i<100000000;i++)
{
"abcd".indexOf("a");
}
long value2 = System.currentTimeMillis();
System.out.println(value2-value1);
value1 = System.currentTimeMillis();
for(long i=0;i<100000000;i++)
{
"abcd".startsWith("a");
}
value2 = System.currentTimeMillis();
System.out.println(value2-value1);
}
}
使用这段代码对它进行测试并且perf for starts似乎更好,因为它显然不需要遍历字符串。但在最好的情况下,两者都应该执行关闭,而在最坏的情况下,启动它将始终比indexOf表现更好