.NET中一些常见代码的性能问题
这是我从前给项目组同事做培训的时候写的一些例子,大家自己可以try一下,看看性能上有什么不同。
1、StringBuilder和String(差别很大)
string s = "";
long t1 = System.DateTime.Now.Ticks;
for(int i=0;i<10000;i++)s += Convert.ToString(i);
long t2 = System.DateTime.Now.Ticks;
long t3 = System.DateTime.Now.Ticks;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for(int i=0;i<10000;i++)sb.Append(Convert.ToString(i));
string s1 = sb.ToString();
long t4 = System.DateTime.Now.Ticks;
long t5 = System.DateTime.Now.Ticks;
System.Text.StringBuilder sb1 = new System.Text.StringBuilder(5000);
for(int i=0;i<10000;i++)sb1.Append(i);
string s2 = sb1.ToString();
long t6 = System.DateTime.Now.Ticks;
long t7 = System.DateTime.Now.Ticks;
System.Text.StringBuilder sb2 = new System.Text.StringBuilder(10000);
for(int i=0;i<10000;i++)sb2.Append(i);
string s3 = sb2.ToString();
long t8 = System.DateTime.Now.Ticks;
ListViewItem item1 = result.Items.Add("使用String类,利用operator +进行操作");
item1.SubItems.Add(Convert.ToString((t2-t1)/10000));
ListViewItem item2 = result.Items.Add("使用StringBuilder类,不对初始大小赋值");
item2.SubItems.Add(Convert.ToString((t4-t3)/10000));
ListViewItem item3 = result.Items.Add("使用StringBuilder类,对初始大小赋值为申请数量的1/2");
item3.SubItems.Add(Convert.ToString((t6-t5)/10000));
ListViewItem item4 = result.Items.Add("使用StringBuilder类,对初始大小赋值为申请数量");
item4.SubItems.Add(Convert.ToString((t8-t7)/10000));
2、异常对性能的影响,当然,下面这个例子没有进行异常的分发、捕获等,所以时间不长。
int j = 0;
long t1 = System.DateTime.Now.Ticks;
for(int i = 0; i < 10000; i++)
{
try
{
j = i;
throw new System.Exception();
}
catch {}
}
long t2 = System.DateTime.Now.Ticks;
long t3 = System.DateTime.Now.Ticks;
for(int i = 0; i < 10000; i++)
{
try
{
j = i;
//throw new System.Exception();
}
catch {}
}
long t4 = System.DateTime.Now.Ticks;
result.Items.Clear();
ListViewItem item1 = result.Items.Add("抛出10000个异常");
item1.SubItems.Add(Convert.ToString((t2-t1)/10000));
ListViewItem item2 = result.Items.Add("屏蔽异常");
item2.SubItems.Add(Convert.ToString((t4-t3)/10000));
3、使用Foreach循环与使用For循环(差别较大)
string s = "monkeys!";
int dummy = 0;
System.Text.StringBuilder sb = new System.Text.StringBuilder(s);
for(int i = 0; i < 1000000; i++)sb.Append(s);
s = sb.ToString();
long t1 = System.DateTime.Now.Ticks;
foreach (char c in s) dummy++;
long t2 = System.DateTime.Now.Ticks;
dummy = 0;
long t3 = System.DateTime.Now.Ticks;
for (int i = 0; i < 1000000; i++)dummy++;
long t4 = System.DateTime.Now.Ticks;
result.Items.Clear();
ListViewItem item1 = result.Items.Add("使用foreach循环");
item1.SubItems.Add(Convert.ToString((t2-t1)/10000));
ListViewItem item2 = result.Items.Add("使用for循环");
item2.SubItems.Add(Convert.ToString((t4-t3)/10000));
4、LateBinding和DirectCall的比较(差别也比较大)
long t1 = System.DateTime.Now.Ticks;
LateBindingTest lbt = new LateBindingTest();
for(int i=0;i<100000;i++)
{
string s = lbt.GetSomewhat();
}
long t2 = System.DateTime.Now.Ticks;
long t3 = System.DateTime.Now.Ticks;
Type t = Type.GetType("PerfDemo.LateBindingTest");
MethodInfo mi = t.GetMethod("GetSomewhat");
for(int i=0;i<100000;i++)
{
object s2 = mi.Invoke(lbt,null);
}
long t4 = System.DateTime.Now.Ticks;
result.Items.Clear();
ListViewItem item1 = result.Items.Add("直接调用class的方法(微秒)");
item1.SubItems.Add(Convert.ToString((t2-t1)/10));
ListViewItem item2 = result.Items.Add("采用迟绑定的方式class的方法(微秒)");
item2.SubItems.Add(Convert.ToString((t4-t3)/10));
5、这是上面例子中使用的class定义:
public class LateBindingTest
{
public string GetSomewhat()
{
return "hello,fqq!";
}
}
6、大家可以结合taskmgr和PerformanceMonitor来进行监视,结论还是比较有意思的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?