Java String.lastIndexOf()字符和具有单个字符的字符串之间有区别吗?
我只是想知道是否有人知道在做以下事情时是否有很大的不同:Java String.lastIndexOf()字符和具有单个字符的字符串之间有区别吗?,java,performance,optimization,Java,Performance,Optimization,我只是想知道是否有人知道在做以下事情时是否有很大的不同: String wibble = "<blah> blah blah </blah>.... <wibble> blah wibble blah </wibble> some more test here"; int i = wibble.lastIndexOf(">"); int j = wibble.lastIndexOf('>'); String wibble=“诸如此类
String wibble = "<blah> blah blah </blah>.... <wibble> blah wibble blah </wibble> some more test here";
int i = wibble.lastIndexOf(">");
int j = wibble.lastIndexOf('>');
String wibble=“诸如此类……诸如此类,诸如此类,在这里进行更多测试”;
int i=wibble.lastIndexOf(“>”);
int j=wibble.lastIndexOf('>');
就性能而言,可能会有细微的差异。对于搜索单个字符,使用char
而不是String
可以更快或等同于使用char
来搜索字符串,无论字符串的长度如何,字符串都需要额外的开销(除非您有一个非常智能的编译器,可以将单个字符串文本优化为字符常量:),因此,如果只搜索单个字符,则应首选字符版本。这不是一个邪恶的优化,因为它在任何方面都是等价的。您实际上可以查看String类的源代码。似乎lastIndex(char)和lastIndex(String)实际上是分开编写的。字符串类也应该有开销。所以char版本可能会快一点,但我怀疑是否会有任何显著的性能差异
在可读性没有差异的地方(如本例),最好使用只搜索字符的版本。lastIndexOf所做的工作更少——在列表中查找单个元素比查找子列表更容易(这实际上就是搜索字符串所做的)。意见很好,但数据更好。我写了一个快速基准: 测试代码
publicstaticvoidmain(字符串[]args)
{
System.out.println(“启动性能测试”);
最终长数值试验=100000000升;
字符串wibble=“诸如此类……”
+“胡扯,胡扯,这里还有更多的测试”;
int x=-1;
秒表sw=新秒表();
System.out.println(“--perfo test with”+NUM_TESTS+“iterations--”);
sw.start();
对于(长i=0;i”);
sw.stop();
System.out.println(“字符串第一次通过:+sw+“秒”);
sw.start();
对于(长i=0;i');
sw.stop();
System.out.println(“字符第一次通过:+sw+“秒”);
sw.start();
对于(长i=0;i');
sw.stop();
System.out.println(“字符第二次通过:+sw+“秒”);
sw.start();
对于(长i=0;i”);
sw.stop();
System.out.println(“字符串第二次传递:+sw+“秒”);
//编译器警告说x从未在本地读取..这是
//确保编译器不会优化“x”。。
系统输出println(x);
}
输出
启动性能测试
--具有100000000次迭代的性能测试--
字符串首次传递:8.750秒
第一次通过:6.500秒
第二遍:6.437秒
字符串第二次传递:8.610秒
63
结论
带有字符的版本大约快25%,但这两个版本执行速度都非常快,因此可能永远不会成为代码的瓶颈。不用担心,这不会造成很大的差异。选择一个更清晰易读的,这是关键。在我看来,一个不可接受的微选择是
如果(needle.length()==1){i=haystack.lastIndexOf(needle.charAt[0]);}否则{…
可能有一个(公认的弱)如果搜索字符串将来可能超过一个字符长,则使用字符串版本进行可维护性的参数,也就是说,如果需要这样的更改,则从“>”
到“/>”
的过程会更少。@Kip:在您需要时可以很容易地进行更改,我的意思是。
public static void main(String[] args)
{
System.out.println("Starting perfo test");
final long NUM_TESTS = 100000000L;
String wibble = "<blah> blah blah </blah>.... <wibble>"
+ " blah wibble blah </wibble> some more test here";
int x = -1;
Stopwatch sw = new Stopwatch();
System.out.println("--perfo test with " + NUM_TESTS + " iterations--");
sw.start();
for(long i = 0; i < NUM_TESTS; i++)
x = wibble.lastIndexOf(">");
sw.stop();
System.out.println("String first pass: " + sw + " seconds");
sw.start();
for(long i = 0; i < NUM_TESTS; i++)
x = wibble.lastIndexOf('>');
sw.stop();
System.out.println("Char first pass: " + sw + " seconds");
sw.start();
for(long i = 0; i < NUM_TESTS; i++)
x = wibble.lastIndexOf('>');
sw.stop();
System.out.println("Char second pass: " + sw + " seconds");
sw.start();
for(long i = 0; i < NUM_TESTS; i++)
x = wibble.lastIndexOf(">");
sw.stop();
System.out.println("String second pass: " + sw + " seconds");
//Compiler warning said x was never read locally.. this is to
//ensure the compiler doesn't optimize "x" away..
System.out.println(x);
}
Starting perfo test
--perfo test with 100000000 iterations--
String first pass: 8.750 seconds
Char first pass: 6.500 seconds
Char second pass: 6.437 seconds
String second pass: 8.610 seconds
63