2019-8-31-C#-程序集数量对软件启动性能的影响
| title | author | date | CreateTime | categories |
|---|---|---|---|---|
|
C# 程序集数量对软件启动性能的影响
|
lindexi
|
2019-08-31 16:55:58 +0800
|
2018-10-17 9:24:3 +0800
|
C# 性能测试
|
本文通过很多的数据测试分析在一个项目引用很多个外部项目和将外部项目的类合并到一个项目之间的启动性能的不同。
通过分析知道了如果一个项目引用了很多项目,而且在启动过程会全部调用这些项目,这时的软件性能会比将这些项目的代码合并到一个项目的慢很多
本文的数据为 预编译框架,开发高性能应用 - 课程 - 微软技术暨生态大会 2018 - walterlv 提供
最近在做一个编译器相关的项目,这个项目是将多个库作为源代码的 nuget 包,这样就可以在开发的时候是使用多个不同的项目,避免项目之间耦合。编译的时候将多个项目编译为 一个 dll 提高了软件启动性能。而且通过源代码包的引用方式可以极大避免了在不同的平台迁移的难度,只要是代码兼容的,甚至代码部分不兼容可以使用宏的方式在不同的平台使用不同的代码。
为了告诉大家这个项目的用处,于是本文就使用代码创建的方式创建了很多代码,通过对比这些代码的运行可以知道将类分在多个项目,和将类放在一个项目在运行过程的性能
我通过创建两个不同的工程,第一个工程是包含一个项目,这个项目里有 5000 个空类,在启动之后会创建这 5000 个类中的 1000 个类。
第二个工程包括了 1000 个项目,每个项目有 5 个空类,这里的空类和前面项目的空类是一样的创建方法。然后再添加一个启动项目,这个启动项目引用了前面的 1000 个项目,在启动之后会创建 1000 个项目中每个项目的一个类,也就是创建了 1000 个类,只是每个类都在不同的项目。
经过了很长时间的编译,我运行了一个项目5000个类的项目,初次运行时间是 54 ms ,接下来两次运行时间分别是 52 ms 和 53 ms 时间很短。
然后运行 1000 个项目,一个项目 5 个类的项目,冷启动时间是 15246 毫秒,之后的运行时间如下
第二次 580 ms
第三次 552 ms
第四次 546 ms
第五次 563 ms
第六次 568 ms
第七次 569 ms
下面表格是对比两个工程运行时间
| 工程 | 冷启动 | 第二次 | 第三次 |
|---|---|---|---|
| 一个项目5000个类 | 54 ms | 52 ms | 53 ms |
| 1000个项目,一个项目5个类 | 15246 ms | 580 ms | 552 ms |
从上面表格可以看到,冷启动的性能差是 280 倍,此后的运行的性能差大概是 10 倍
然后我还测试了 1000 个项目,一个项目 1000 个类的运行时间,冷启动 22993 毫秒,热启动三次的数据是 885 毫秒,871 毫秒和 861 毫秒
测试项目的代码可以从 csdn 下载,如果没有积分请发邮件给我。如果觉得上面的数据很诡异,请自己运行一下编译一下
创建测试项目的代码请看下面
创建一个项目这个项目里有 5000 个类,在启动之后调用这 5000 个类里的 1000 个
{% raw %}
private static void LownearkeajooSasouStegisti()
{
var saryawpirmiGerekipoNehiti = new DirectoryInfo("MayairJowya"); saryawpirmiGerekipoNehiti.Create(); var fawniSorhaHereni = new List<string>(); var deleeTacarirouWulall = new WhairchooHerdo(); for (int gupoudigorKihirkercou = 0; gupoudigorKihirkercou < 1000; gupoudigorKihirkercou++)
{
var teaJawtu = deleeTacarirouWulall.LemgeDowbovou(); for (int mirxarJeredrairsear = 0; mirxarJeredrairsear < 5; mirxarJeredrairsear++)
{
var cicirRarsonisallJearwelxe = deleeTacarirouWulall.LemgeDowbovou(); var facoSaijeesereniXaimow = $@"
using System;
using System.Collections.Generic;
using System.Text; namespace {teaJawtu}
{{
public class {cicirRarsonisallJearwelxe}
{{
public string Foo {{ get; set; }}
}}
}}";
if (mirxarJeredrairsear == 0)
{
fawniSorhaHereni.Add(teaJawtu + "." + cicirRarsonisallJearwelxe);
} File.WriteAllText(
Path.Combine(saryawpirmiGerekipoNehiti.FullName, cicirRarsonisallJearwelxe + ".cs"),
facoSaijeesereniXaimow);
}
} var jawjearPalfokallPuwuTearbourer = new StringBuilder(); jawjearPalfokallPuwuTearbourer.Append(@"<Project Sdk=""Microsoft.NET.Sdk""> <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup> <ItemGroup>
"); jawjearPalfokallPuwuTearbourer.Append(@" </ItemGroup> </Project>"); File.WriteAllText(Path.Combine(saryawpirmiGerekipoNehiti.FullName, "TirkalltremceFalgawCouwabupu.csproj"),
jawjearPalfokallPuwuTearbourer.ToString()); jawjearPalfokallPuwuTearbourer.Clear(); var cepepiSowneKorrer = @"using System;
using System.Diagnostics; namespace CouwharjeMerball
{
class Program
{
static void Main(string[] args)
{
var dafuWhayroubaXouma = new Stopwatch();
dafuWhayroubaXouma.Start();
var kawgeDeesearsofas = new KawgeDeesearsofas();
kawgeDeesearsofas.LurtrajaboPearbubirXinene();
dafuWhayroubaXouma.Stop();
Console.WriteLine(dafuWhayroubaXouma.ElapsedMilliseconds);
}
}
}
";
File.WriteAllText(Path.Combine(saryawpirmiGerekipoNehiti.FullName, "Program.cs"), cepepiSowneKorrer); jawjearPalfokallPuwuTearbourer.Append(@"namespace CouwharjeMerball
{
class KawgeDeesearsofas
{
public void LurtrajaboPearbubirXinene()
{
"); foreach (var ferosarTadir in fawniSorhaHereni)
{
jawjearPalfokallPuwuTearbourer.Append(" new " + ferosarTadir + "();");
jawjearPalfokallPuwuTearbourer.Append("\r\n");
} jawjearPalfokallPuwuTearbourer.Append(@" }
}
}"); File.WriteAllText(Path.Combine(saryawpirmiGerekipoNehiti.FullName, "KawgeDeesearsofas.cs"),
jawjearPalfokallPuwuTearbourer.ToString());
}
{% endraw %}
创建 1000 个项目,每个项目有 5 个类,在启动项目引用这 1000 个项目,在启动之后创建 1000 个类,这 1000 个类每个类都在不同的项目里
{% raw %}
private static void KijeSabacher()
{
var jisqeCorenerairTurpalhee = new DirectoryInfo("StuLartearou"); jisqeCorenerairTurpalhee.Create(); var jairtallworBeakoo = new WhairchooHerdo(); List<string> geeberecereHouroudo = new List<string>(); List<string> xawsosapawTabejetai = new List<string>(); for (int qeltasmisVigallSearniste = 0; qeltasmisVigallSearniste < 1000; qeltasmisVigallSearniste++)
{
string louwebirPemtrasrereYorta = ""; var fismeerurniDawwall = jairtallworBeakoo.LemgeDowbovou(); var nemirchouDamounu = jisqeCorenerairTurpalhee.CreateSubdirectory(fismeerurniDawwall); var beltuzoKoma = @"<Project Sdk=""Microsoft.NET.Sdk""> <PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup> </Project>
";
xawsosapawTabejetai.Add(fismeerurniDawwall); File.WriteAllText(Path.Combine(nemirchouDamounu.FullName, fismeerurniDawwall + ".csproj"), beltuzoKoma); for (int roupairDufallne = 0; roupairDufallne < 5; roupairDufallne++)
{
var whowjallKelpirhorWirweSemjaneldroo = jairtallworBeakoo.LemgeDowbovou(); if (roupairDufallne == 0)
{
louwebirPemtrasrereYorta = fismeerurniDawwall + "." + whowjallKelpirhorWirweSemjaneldroo;
} var facoSaijeesereniXaimow = $@"
using System;
using System.Collections.Generic;
using System.Text; namespace {fismeerurniDawwall}
{{
public class {whowjallKelpirhorWirweSemjaneldroo}
{{
public string Foo {{ get; set; }}
}}
}}"; File.WriteAllText(
Path.Combine(nemirchouDamounu.FullName, whowjallKelpirhorWirweSemjaneldroo + ".cs"),
facoSaijeesereniXaimow);
} geeberecereHouroudo.Add(louwebirPemtrasrereYorta);
} var jawjearPalfokallPuwuTearbourer = new StringBuilder(); var dirceDadaipaHowbistairneeQabijel = "CouwharjeMerball";
var suleLougirwhe = jisqeCorenerairTurpalhee.CreateSubdirectory(dirceDadaipaHowbistairneeQabijel); jawjearPalfokallPuwuTearbourer.Append(@"<Project Sdk=""Microsoft.NET.Sdk""> <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup> <ItemGroup>
"); foreach (var ciraZeajanipou in xawsosapawTabejetai)
{
jawjearPalfokallPuwuTearbourer.Append(
$@" <ProjectReference Include=""..\{ciraZeajanipou}\{ciraZeajanipou}.csproj"" />");
jawjearPalfokallPuwuTearbourer.Append("\r\n");
} jawjearPalfokallPuwuTearbourer.Append(@" </ItemGroup> </Project>"); File.WriteAllText(Path.Combine(suleLougirwhe.FullName, dirceDadaipaHowbistairneeQabijel + ".csproj"),
jawjearPalfokallPuwuTearbourer.ToString()); jawjearPalfokallPuwuTearbourer.Clear(); var cepepiSowneKorrer = @"using System;
using System.Diagnostics; namespace CouwharjeMerball
{
class Program
{
static void Main(string[] args)
{
var dafuWhayroubaXouma = new Stopwatch();
dafuWhayroubaXouma.Start();
var kawgeDeesearsofas = new KawgeDeesearsofas();
kawgeDeesearsofas.LurtrajaboPearbubirXinene();
dafuWhayroubaXouma.Stop();
Console.WriteLine(dafuWhayroubaXouma.ElapsedMilliseconds);
}
}
}
";
File.WriteAllText(Path.Combine(suleLougirwhe.FullName, "Program.cs"), cepepiSowneKorrer); jawjearPalfokallPuwuTearbourer.Append(@"namespace CouwharjeMerball
{
class KawgeDeesearsofas
{
public void LurtrajaboPearbubirXinene()
{
"); foreach (var ferosarTadir in geeberecereHouroudo)
{
jawjearPalfokallPuwuTearbourer.Append(" new " + ferosarTadir + "();");
jawjearPalfokallPuwuTearbourer.Append("\r\n");
} jawjearPalfokallPuwuTearbourer.Append(@" }
}
}"); File.WriteAllText(Path.Combine(suleLougirwhe.FullName, "KawgeDeesearsofas.cs"),
jawjearPalfokallPuwuTearbourer.ToString());
}
{% endraw %}
{% raw %}
{% endraw %}
参见
2019-8-31-C#-程序集数量对软件启动性能的影响的更多相关文章
- C# 程序集数量对软件启动性能的影响
本文通过很多的数据测试分析在一个项目引用很多个外部项目和将外部项目的类合并到一个项目之间的启动性能的不同. 通过分析知道了如果一个项目引用了很多项目,而且在启动过程会全部调用这些项目,这时的软件性能会 ...
- OSCHINA 公布 2019 年度最受欢迎中国开源软件
https://www.oschina.net/project 此文章从此处转载:https://www.oschina.net/project/top_cn_2019?utm_source=star ...
- agentzh 的 Nginx 教程(版本 2019.07.31)
agentzh 的 Nginx 教程(版本 2019.07.31) agentzh 的 Nginx 教程(版本 2019.07.31) https://openresty.org/download/a ...
- 2019 第十届蓝桥杯大赛软件类省赛 Java A组 题解
2019 第十届蓝桥杯大赛软件类省赛 Java A组 试题A 题解 题目最后一句贴心的提示选手应该使用 long (C/C++ 应该使用 long long). 本题思路很直白,两重循环.外层 ...
- C# 程序内的类数量对程序启动的影响
原文:C# 程序内的类数量对程序启动的影响 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee.i ...
- 2018-10-31-C#-程序内的类数量对程序启动的影响
title author date CreateTime categories C# 程序内的类数量对程序启动的影响 lindexi 2018-10-31 14:7:6 +0800 2018-10-1 ...
- OSGi 对软件复杂度的影响
出自 深度理解 osgi equinox 原理 1.2.1 OSGi 能让软件开发变得更容易吗 不可否认,OSGi 的入门门槛在 Java 众多技术中算是比较高的,相对陡峭的学习曲线会 为第一次使用 ...
- bootchart--检测linux启动性能的软件
bootchart--检测linux启动性能的软件 摘自http://www-128.ibm.com/developerworks/library/l-boot-faster/index.html?c ...
- Win10如何禁止软件运行?win10禁止软件启动的设置方法!禁止人生日历热点快讯的方法
相信不少使用Win10系统的用户遇到过下载了一款软件进行安装后后续会有接连不断的程序安装到电脑中.他可能似乎一个大家常用的程序,在我们安装好运行的时候会通过后台偷偷下载其他应用安装到我们电脑中,导致系 ...
随机推荐
- IMS Call中的SS
1Hold procedure:对于每一个被HOLD的媒体流,SDP包含: 如果流之前被设置为“recvonly”媒体流则是一个“不活动”的SDP属性: 如果先前将流设置为“sendrecv”媒体流则 ...
- 9个搜索引擎优化(SEO)最佳实践
作为网页设计师,搜索引擎优化重要吗?我们知道,网站设计是把屏幕上平淡无奇变成令人愉快的美感,更直观地辨认信息.这也是人与人之间在沟通想法,这样的方式一直在演变. 1. 网站结构 对于搜索引擎优化,网站 ...
- threading线程中的方法(27-11)
t1.start() # 执行线程 t1.join() # 阻塞 t1.setDaemon(True) #守护线程 threading.current_thread() # 查看执行的是哪一个线程 t ...
- Go前言
Go语言为并发而生 硬件制造商正在为处理器添加越来越多的内核以来提高性能.所有数据中心都在这些处理器上运行,今天的应用程序使用多个微服务来维护数据库连接,消息队列和维护缓存.所以,开发的软件和编程语言 ...
- 移植 Busybox
下载 busybox 从 http://www.busybox.net/downloads/busybox1.1.3.tar.gz/下载 busybox1.1.3 到/tmp 目录当中,并解压. ...
- 使用HttpStaus自定义返回状态
一.导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- https://webpack.js.org/plugins/
有问题还是看源码 ,看官方文档吧,整一晚上终于整明白了
- AM运行中的垃圾数据清理
1.下载 filetmpclear.bat 2.打开 这个批处理文件,修改参数 3.按下图 第一个红色框内, 地址: 可以在 AM8服务管理器- 文件服务 ,数据路径后再加 \__Temp__ 第 ...
- Django问题
Django问题 'WSGIRequest' object has no attribute 'user' django python 关注 2 关注 收藏 0 收藏,413 浏览 当我的djan ...
- 12DUILib经典教程(实例)
Duilib经典实例教程:1基本框架:一个简单的Duilib程序一般是下面这个样子的:://Duilib使用设置部分:#pragmaonce:#defineWIN32_LEAN_AND_ME:#def ...