2009-06-30 272 views
3

我正在用Java编写代码,我根据string是否以某些字符开头,而通过dataset循环播放,而我的dataset预计会很大。“startsWith”比“indexOf”更快吗?

我想知道startsWith是否比indexOf更快。我做了2000个记录的实验,但没有发现任何区别。

回答

-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为startsWith测试它似乎更好,为明显的原因,它并没有通过字符串遍历。但是,在最好的情况下都应该执行关闭,而在最坏的情况下startsWith永远比的indexOf有更好的表现

2

也许,如果它不匹配,它可能会停止查找,而indexOf需要在字符串的稍后查找出现。

5

即使不看到源,它应当清楚的是startsWith至少快于大字符串和短图案:

(b)的结合a.startsWith的运行时间是b的长度。在最多检查到第一个b字符后,搜索结束。

a.indexOf(b)的运行时间较长(取决于actual algorithm)。每个算法至少有一个运行时间取决于a的长度。粗略地说,你可以说,你必须查看每个角色一次来检查模式是否在该位置开始。

但是,如果您真的在实践中看到不同,它将一如既往地取决于实际使用情况。衡量现实生活中的差异永远不会是坏事。

+1

我认为你的第一句话是倒退...... * startsWith *至少对于大字符串和短格式来说更快...... – 2009-06-30 06:51:04

+1

Jon Skeet是对的。我改变了它。 – dmeister 2009-06-30 07:34:03

6

一般情况下,微型优化的黄金法则适用于这里:

“措施,不要猜测”。

与所有这种类型的优化一样,两个调用之间的差异几乎肯定不会影响,除非您检查数以百万计的字符长度为几万个字符。

在您的代码上运行一个分析器,并且只有在您可以测量出它降低速度时才优化此调用。直到那时,使用更易读的选项(在这种情况下,startsWith)。一旦你知道这个模块正在减慢你的速度,那么试试这两个模块,并使用更快的模块。冲洗。重复;-)

在学术上,我的猜测是startsWith可能会使用indexOf来实现。检查源代码,看看你是否感兴趣。 (原来这个startsWith并没有调用indexOf)

+0

我真的*真的*希望startsWith没有用indexOf实现。考虑“一些非常长的字符串,它不以x开始”.startsWith(“x”) - 检查第一个字符后应该返回有效的实现,而使用indexOf可能需要查看整个字符串。 – 2009-06-30 06:56:11

9

startsWith只需要检查字符串开头的存在情况 - 它的工作量减少了,所以它应该更快。

我的猜测是你的2000个记录在几毫秒内完成(如果有的话)。无论何时您想将一种方法与另一种方法进行基准比较,请尝试在足够的时间内完成,以便时间差异显着。我发现10-30秒足以显示出明显的改善,但足够短以使其能够多次运行测试。 (如果这是一个严肃的调查中,我大概会尝试更长的时间我的大部分标杆是为了好玩。)

另外,还要确保你有不同的数据 - indexOfstartsWith应该有大致相同的运行时间indexOf返回0的情况下。所以如果你所有的记录都符合这个模式,那么你并没有真正地进行测试。 (当然,我不知道你的测试是否属于这种情况 - 这只是需要注意的一点。)

0

您提到数据集预计会很大。所以我敢打赌,很多performanve会进入这个数据集并在内存中处理它。这意味着使用一个或另一个不会改变显着的性能。但是如果这对你很重要,你可以编写自己的startWith方法,这个方法可能比标准库方法快得多,或者至少你知道完成了什么。

1

startsWith比的indexOf == 0更清晰

你有没有确定测试的性能瓶颈,其你需要牺牲可读性?