判断字符串是否为空经常用到String.InNullOrEmpty方法,今天想试试它的速度有多快,结果遇到了一个有点奇怪的问题。
用Reflector把String.InNullOrEmpty方法的代码反射出来复制到自己的代码中去调用和直接调用String.InNullOrEmpty的速度竟然会相差3-4倍。而如果把String.Format反射并复制到自己的代码中调用却和直接调用String.Format没有多大区别。代码如下,请各位帮忙分析一下。using System;namespace ConsoleApplication1
{
class Program
{
static DateTime startTime; static void Main(string[] args)
{
string str = "hello";
for (int i = 0; i < 10; i++)
{
RunItInTwoWays(str);
Console.WriteLine("----------------");
}
Console.ReadLine();
} private static void RunItInTwoWays(string str)
{
Start();
for (int i = 0; i < 10000000; i++)
{
string.IsNullOrEmpty(str);
}
PrintTimeSpan(); Start();
for (int i = 0; i < 10000000; i++)
{
IsNullOrEmpty(str);
}
PrintTimeSpan();
} private static void Start()
{
startTime = DateTime.Now;
} private static void PrintTimeSpan()
{
TimeSpan elapsedTime = DateTime.Now - startTime;
Console.WriteLine(elapsedTime);
} public static bool IsNullOrEmpty(string value)
{
if (value != null)
{
return (value.Length == 0);
}
return true;
}
}
}
用Reflector把String.InNullOrEmpty方法的代码反射出来复制到自己的代码中去调用和直接调用String.InNullOrEmpty的速度竟然会相差3-4倍。而如果把String.Format反射并复制到自己的代码中调用却和直接调用String.Format没有多大区别。代码如下,请各位帮忙分析一下。using System;namespace ConsoleApplication1
{
class Program
{
static DateTime startTime; static void Main(string[] args)
{
string str = "hello";
for (int i = 0; i < 10; i++)
{
RunItInTwoWays(str);
Console.WriteLine("----------------");
}
Console.ReadLine();
} private static void RunItInTwoWays(string str)
{
Start();
for (int i = 0; i < 10000000; i++)
{
string.IsNullOrEmpty(str);
}
PrintTimeSpan(); Start();
for (int i = 0; i < 10000000; i++)
{
IsNullOrEmpty(str);
}
PrintTimeSpan();
} private static void Start()
{
startTime = DateTime.Now;
} private static void PrintTimeSpan()
{
TimeSpan elapsedTime = DateTime.Now - startTime;
Console.WriteLine(elapsedTime);
} public static bool IsNullOrEmpty(string value)
{
if (value != null)
{
return (value.Length == 0);
}
return true;
}
}
}
也就3倍的样子
string.IsNullOrEmpty(str);
这个确实会快些反汇编 IsNullOrEmpty跟不进去不知道IsNullOrEmpty 是怎么实现的
方法是动态调用的,但是应该只有第一次调用的时候才会JIT啊
public static bool IsNullOrEmpty(string value)
{
if (value != null)
{
return (value.Length == 0);
}
return true;
}
找到mscorlib程序集,然后是System命名空间,然后string类型下的IsNullOrEmpty方法。
return (value == null || value.Length == 0);
}
.method public hidebysig static bool IsNullOrEmpty(string 'value') cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: brfalse.s L_000d
L_0003: ldarg.0
L_0004: callvirt instance int32 System.String::get_Length()
L_0009: ldc.i4.0
L_000a: ceq
L_000c: ret
L_000d: ldc.i4.1
L_000e: ret
}编译的就是这段IL。
谢谢,刚才试了一下,release anycpu编译的,在IDE之外运行的,直接调用String.IsNullOrEmpty和调用自己编译IL得到的程序集速度基本一致。
但是IL应该是一样的。
reflector出来的C#再次编译为IL是和原始的不一样