看到的一道面试题,但是我不知道(3)是哪里的。
(1)string str1 = "",(2)string str1 = null,(3)string str1 = string.Length = 0;
上面三个式子哪个运行更快? 期待高手解答。并解释清楚
(1)string str1 = "",(2)string str1 = null,(3)string str1 = string.Length = 0;
上面三个式子哪个运行更快? 期待高手解答。并解释清楚
(1)声明并建立了一个长度为0的字符串对象,分配了内存空间;(2)跟String str1一样,没有分配。
基于Java时间的精度,看不出来谁快,但理论上应该是(2)快。
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
long start = System.currentTimeMillis(); String[] s = new String[100000]; for (int i = 0; i < s.length; i++) {
//s[i] = ""; //第一个 3078ms
//s[i] = null; //第二个 3125ms
} for (String e : s) {
System.out.println("测试时间开销:" + e);
} long end = System.currentTimeMillis();
System.out.println("程序执行时间:"+(end - start) + "ms"); }}
""在字符串池中.
long start;
long end;
start = System.currentTimeMillis();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
//自己可以换成 null 试试。
String str1 = "";
}
end = System.currentTimeMillis();
System.out.println(end-start);
}}
以上第二条是我的推测没有根据,希望研究JVM的高手给予指点。一下是本人测试代码:
创建空字符串类:
package com.common;public class BulidSpaceString {
public static void bulidSpace(Integer con){
int i=0;
for (i = 0; i < con.intValue(); i++) {
String a="";
}
System.out.println(i);
}
}创建null类:package com.common;
public class BuildNullString {
public static void buildNull(Integer con){
int i=0;
for (i = 0; i < con.intValue(); i++) {
String a=null;
}
System.out.println(i);
}
}测试基类:package com.common;import java.lang.reflect.Method;
import java.util.List;public class RunTime { /**
* 通过方法名动态调用对象方法
*
* @param clsName
* 调用类
* @param methodName
* 方法名
* @param args
* 方法参数
* @return
* @throws Exception
*/
public static long invokeStaticMethod(String clsName, String methodName,
Object[] args) throws Exception {
long start = System.nanoTime();
try {
Class c = Class.forName(clsName);
Class[] argsClass = new Class[] {Integer.class};
Method method = c.getMethod(methodName, argsClass);
method.invoke(c, args);
} catch (Exception e) {
e.printStackTrace();
}
long end = System.nanoTime();
return end - start;
}
}测试核心区:package com.common;import java.util.ArrayList;
import java.util.List;public class TestSpaceForString {
public static void main(String[] args) {
Integer a=100000;
Object[] param=new Object[]{a};
try {
long runTime=RunTime.invokeStaticMethod("com.lfpost.common.BuildNullString", "buildNull", param);
System.out.println("采用BuildNullString转化方法执行时间"+runTime);
long runTimeByColl=RunTime.invokeStaticMethod("com.lfpost.common.BulidSpaceString", "bulidSpace", param);
System.out.println("采用BulidSpaceString执行时间"+runTimeByColl);
System.out.println("微秒相差(runTimeByColl-runTime)=" +String.valueOf(runTimeByColl-runTime));
} catch (Exception e) {
e.printStackTrace();
}
}
}-------------------------------------------------------------
100000
采用BuildNullString转化方法执行时间5007061
100000
采用BulidSpaceString执行时间3681474
微秒相差(runTimeByColl-runTime)=-1325587说白了是String abc="" 快一些!可能我这么测试不合理大家指正!
for (String e : s) {
System.out.println("测试时间开销:"+ e);
感觉把这段代码去掉好象是2比较快一些
我在机器上测试的代码如下,我的机器比较快,我把FOR循环改成500万到1000万次public class TestXiaolv { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
long start = System.currentTimeMillis(); String[] s = new String[5000000]; for (int i = 0; i < s.length; i++) {
s[i] = "";
s[i] = null;
}
long end = System.currentTimeMillis();
System.out.println("程序执行时间:"+(end - start) + "ms"); }}可以试试看,一起讨论
{
public static void main(String[] args)
{
long timestart,timeend;
timestart=System.nanoTime();
String str1="";
timeend=System.nanoTime();
System.out.println("str1时间:"+(timeend-timestart));
timestart=System.nanoTime();
String str2=null;
timeend=System.nanoTime();
System.out.println("str2时间:"+(timeend-timestart));
}
}
public static void buildNull(Integer con){
int i=0;
for (i = 0; i < con.intValue(); i++) {
String a=null;
}
System.out.println(i);}}class RunTime {/**
* 通过方法名动态调用对象方法
*
* @param clsName
* 调用类
* @param methodName
* 方法名
* @param args
* 方法参数
* @return
* @throws Exception
*/
public static long invokeStaticMethod(String clsName, String methodName,
Object[] params) throws Exception {
long start = System.nanoTime();
try {
Class c = Class.forName(clsName);
Class[] paramsClass = new Class[] {Integer.class};
Method method = c.getMethod(methodName, paramsClass);
method.invoke(c, params);
} catch (Exception e) {
e.printStackTrace();
}
long end = System.nanoTime();
return end - start;
}
}public class TestSpaceForString {
public static void main(String[] args) {
Integer a=100000;
Object[] param=new Object[]{a};
try {long runTimeByColl=RunTime.invokeStaticMethod("BulidSpaceString", "bulidSpace", param);
System.out.println("采用BulidSpaceString执行时间"+runTimeByColl);
long runTime=RunTime.invokeStaticMethod("BuildNullString", "buildNull", param);
System.out.println("采用BuildNullString转化方法执行时间"+runTime);
System.out.println("微秒相差(runTimeByColl-runTime)=" +String.valueOf(runTimeByColl-runTime));
} catch (Exception e) {
e.printStackTrace();
}
}
}
一样的将 for 和输出全部去掉采用BuildNullString转化方法执行时间2528254
采用BulidSpaceString执行时间1340673
微秒相差(runTimeByColl-runTime)=-1187581还是 空串快一些!
前2个要从Opcode入手,2者的Opcode的区别在于
1)String s1=""; 用的是 ldc [""在常量池的index]
2)String s2=null; 用的是 aconst_null
在运行时,第一个要访问2次内存,分别是读取ldc指令和读取index,而第2个只访问一次。
所以,第二个快。