当前位置: 首页 > news >正文

企业网站招聘可以怎么做做网站,图片显示不出来

企业网站招聘可以怎么做,做网站,图片显示不出来,平台设计什么意思,seo推广公司招商字符串池化#xff0c;减少重复实例#xff0c;内存降低#xff0c;一切就是这样的轻松愉快。开篇摘要 本文通过一个简单的业务场景#xff0c;来描述如何通过字符串池化来减少内存中的重复字符串实例#xff0c;从而减少内存的占用。在业务中#xff0c;我们假设如下减少重复实例内存降低一切就是这样的轻松愉快。开篇摘要 本文通过一个简单的业务场景来描述如何通过字符串池化来减少内存中的重复字符串实例从而减少内存的占用。在业务中我们假设如下有一百万个商品每个商品都有一个 ProductId 和 Color 列保存在数据库中需要将所有的数据加载到内存中作为缓存使用每个产品都有 ColorColor 的范围是一个有限的范围我们假设大约为八十个左右学习 dotMemory 度量内存 既然需要度量内存优化的可靠性那么一个简单有效的度量工具自然必不可少。本篇我们介绍 Rider dotMemory 的组合如何进行简单的内存度量。读者也可以根据自己的实际选择自己青睐的工具。首先我们创建一个单元测试项目并且编写一个简单的内存字典构建过程: public const int ProductCount  1_000_000;public static readonly Liststring Colors  new[]{amber, // 此处实际上有80个左右的字符串省略篇幅}.OrderBy(x  x).ToList();public static Dictionaryint, ProductInfo CreateDict() {var random  new Random(36524);var dict  new Dictionaryint, ProductInfo(ProductCount);for (int i  0; i  ProductCount; i){dict.Add(i, new ProductInfo{ProductId  i,Color  Colors[random.Next(0, Colors.Count)]});}return dict; } 从以上代码可以看出创建了一百万个商品对象其中的 Color 通过随机数进行随机选取。提前指定字典的大小的预期值实际上也是一种优化。请参阅https://docs.microsoft.com/dotnet/api/system.collections.generic.dictionary-2.-ctor?viewnet-5.0WT.mc_idDX-MVP-5003606#System_Collections_Generic_Dictionary_2__ctor_System_Int32_然后我们引入 dotMemory 单元测试度量必要的 nuget 包和其他一些无关紧要的包:ItemGroupPackageReference IncludeJetBrains.DotMemoryUnit Version3.1.20200127.214830 /PackageReference IncludeHumanizer Version2.11.10 / /ItemGroup 接着我们创建一个简单的测试来度量以上字典的创建前后内存的变化public class NormalDictTest {[Test][DotMemoryUnit(FailIfRunWithoutSupport  false)]public void CreateDictTest(){var beforeStart  dotMemory.Check();var dict  HelperTest.CreateDict();GC.Collect();dotMemory.Check(memory {var snapshotDifference  memory.GetDifference(beforeStart);Console.WriteLine(snapshotDifference.GetNewObjects().SizeInBytes.Bytes());});} } 从以上代码可以看出在字典创建之前我们通过dotMemory.Check()来捕捉当前内存的快照以便后续进行对比字典创建完毕后我们比对前后两次检查点中新增的对象的大小。最后点击如下图所示的按钮运行这个测试run dotMemory那么就会到的如下这样的结果result故而我们可以得出这样一个简单的结论。这样一个字典大约需要 61MB 的内存。而这是理论上这个字典占用了内存最小情况。因为其中每个 Color 使用的都是上面的八十个范围之一。因此他们达到了没有任何重复实例的目的。这个数据将会作为后续代码的一个基准。尝试从数据库载入到内存 实际业务肯定是从数据库之类的持久化存储载入到内存中的。因此我们度量一下没有经过优化情况下这种载入方式大概需要多大的内存开销。这里我们使用 SQLite 作为演示的存储数据库实际上用什么都可以因为我们关心的是最终缓存的大小。我们引入一些无关紧要的包ItemGroupPackageReference IncludeDapper Version2.0.90 /PackageReference IncludeSystem.Data.SQLite.Core Version1.0.115 / /ItemGroup 我们编写一个测试代码将一百万测试数据写入到测试库中[Test] public async Task CreateDb() {var fileName  data.db;if (File.Exists(fileName)){return;}var connectionString  GetConnectionString(fileName);await using var sqlConnection  new SQLiteConnection(connectionString);await sqlConnection.OpenAsync();await using var transaction  await sqlConnection.BeginTransactionAsync();await sqlConnection.ExecuteAsync( CREATE TABLE Product(ProductId int PRIMARY KEY,Color TEXT ), transaction);var dict  CreateDict();foreach (var (_, p) in dict){await sqlConnection.ExecuteAsync( INSERT INTO Product(ProductId,Color) VALUES(ProductId,Color), p, transaction);}await transaction.CommitAsync(); }public static string GetConnectionString(string filename) {var re $Data Source{filename};Cache Size5000;Journal ModeWAL;PoolingTrue;Default IsolationLevelReadCommitted;return re; } 以上代码创建一个名为 data.db 的数据在数据库中创建一个 Product 表包含 ProductId 和 Color 两列将字典中的所有数据插入到这两个表中其实就是前文创建的那个字典运行这个测试大概十秒左右测试数据也就准备好了。后续我们将重复从这个数据库读取数据作为我们的测试用例。现在我们编写一个从数据库读取数据然后载入到字典的代码并且度量一下内存的变化[Test] [DotMemoryUnit(FailIfRunWithoutSupport  false)] public async Task LoadFromDbAsync() {var beforeStart  dotMemory.Check();var dict  new Dictionaryint, ProductInfo(HelperTest.ProductCount);await LoadCoreAsync(dict);GC.Collect();dotMemory.Check(memory {var snapshotDifference  memory.GetDifference(beforeStart);Console.WriteLine(snapshotDifference.GetNewObjects().SizeInBytes.Bytes());}); }public static async Task LoadCoreAsync(Dictionaryint, ProductInfo dict) {var connectionString  HelperTest.GetConnectionString();await using var sqlConnection  new SQLiteConnection(connectionString);await sqlConnection.OpenAsync();await using var reader  await sqlConnection.ExecuteReaderAsync(SELECT ProductId, Color FROM Product);var rowParser  reader.GetRowParserProductInfo();while (await reader.ReadAsync()){var productInfo  rowParser.Invoke(reader);dict[productInfo.ProductId]  productInfo;} } 以上代码我们改变了字典的创建方式将其中的数据从数据库中读取并载入使用 Dapper 读取 DataReader 并且全部载入字典同样我们运行 dotMemory 度量变化可以得到数据为95.1 MB 因此我们得出采用这种方式多消耗了 30MB 左右的内存。看起来很少但其实比前面多了 50%。一千五工资加薪到三千涨薪 100%的即时感当然你可能会怀疑多出来的这些开销实际上是数据库操作消耗的。但通过下文的优化我们可以提前知道这些多出来的开销实际上是因为存在重复的字符串消耗。剔除重复的字符串实例 既然我们怀疑多出来的开销是重复的字符串那么我们就可以考虑通过将它们转为同一个对象的方式减少字典中重复的字符串。所以我们就有了下面这个版本的测试代码[Test] [DotMemoryUnit(FailIfRunWithoutSupport  false)] public async Task LoadFromDbAsync() {var beforeStart  dotMemory.Check();var dict  new Dictionaryint, ProductInfo(HelperTest.ProductCount);await DbReadingTest.LoadCoreAsync(dict);foreach (var (_, p) in dict){var colorIndex  HelperTest.Colors.BinarySearch(p.Color);var color  HelperTest.Colors[colorIndex];p.Color  color;}GC.Collect();dotMemory.Check(memory {var snapshotDifference  memory.GetDifference(beforeStart);Console.WriteLine(snapshotDifference.GetNewObjects().SizeInBytes.Bytes());}); } 以上代码我们仍然从数据库载入所有的数据到字典中载入的代码和先前完全一样因此没有展示载入之后我们再次遍历字典。并且从早在第一个版本就存在的 Color List 搜索到对应的字符串实例并且赋值给字典中的 Color通过这样一搜一读一换。我们使得字典中的 Color 全部来自 Color List于是我们再次运行 dotMemory 进行度量结果非常的 Amazing61.69 MB 虽说最终这个数字的开销对比第一个版本略有上升但其实已经到了相差无几的地步。我们通过将相同字符串转为相同实例的方式将字典中的相同 Color 转为了相同实例。而 30MB 的临时字符串则会由于没有对象引用它们因此在最近的一次 GC 中会被立即回收一切都是这样的轻松愉快。直接引入 StringPool 前文我们已经找到了开销的原因并且通过办法进行了优化。不过还存在一些问题实际上要考虑很多时候 Color List 并不是静态的列表她可能早上还很开心下午就生气了Color List 不可能无限大我们需要一个淘汰算法淘汰末尾的 10%把他们输送给社会因此我们可以考虑直接使用 StringPool别人写的代码很棒现在是我们的了。让我们再引入一些无关紧要的包ItemGroupPackageReference IncludeMicrosoft.Toolkit.HighPerformance Version7.0.2 / /ItemGroup 稍微改了一下就有了新的版本[Test] [DotMemoryUnit(FailIfRunWithoutSupport  false)] public async Task LoadFromDbAsync() {var beforeStart  dotMemory.Check();var dict  new Dictionaryint, ProductInfo(HelperTest.ProductCount);await DbReadingTest.LoadCoreAsync(dict);var stringPool  StringPool.Shared;foreach (var (_, p) in dict){p.Color  stringPool.GetOrAdd(p.Color);}GC.Collect();dotMemory.Check(memory {var snapshotDifference  memory.GetDifference(beforeStart);Console.WriteLine(snapshotDifference.GetNewObjects().SizeInBytes.Bytes());}); } 以上代码使用了 StringPool.Shared 实例存储字符串实例GetOrAdd 实际上就是实现了我们先前的一搜一读一换三步走战略当然结果也是毫无惊喜可言的惊喜61.81 MB 一切就是这样的轻松愉快。diff延伸阅读 StringPool 和 string.Intern() 有什么异同它们都是为了解决重复字符串实例过多导致浪费内存的情况。效果上的区别主要是生存期的区别。string.Intern 是终生制的一旦加入只要程序不重启就会一直存在。这和 StringPool 很不一样。因此如果你有生存期上的考虑请斟酌选择。string.Intern 可以参阅https://docs.microsoft.com/dotnet/api/system.string.intern?viewnet-5.0WT.mc_idDX-MVP-5003606StringPool 是怎么实现的咱也不懂咱也不敢乱说。总的来说是一个带有使用计数标记的优先队列。源代码咱也读不懂。前面的区域就交给你探索吧https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/main/Microsoft.Toolkit.HighPerformance/Buffers/StringPool.cs我该在什么情况下考虑使用 StringPool笔者建议考虑这些字符串入池这个字符串可能被很多实例引用这个字符串需要长期驻留或者持有它的对象是长期对象内存优化确实已经成为你要考虑的事情了当然其实存在一个最容易判断的依据。你可以直接把产线上的内存 dump 下来查看里面是否存在很多重复的字符串然后优化他们。现在已经是 2021 年了不会还有人不会 dump 内存吧不会吧不会吧手动狗头 如果你还不会 dump 内存那么可以参阅黄老师在微软 Reactor 上分享的视频进行学习https://www.bilibili.com/video/BV1jZ4y1P7EY好耶我可以用 StringPool 来存储枚举的 DisplayName确实也没有什么错。不过其实还有更好的一些方案:https://github.com/Spinnernicholas/EnumFastToStringDotNet本篇小结 dotMemory 度量还有更多姿势你可以多多尝试。重复池化。这是一种非常常见的优化方案。掌握它们在你需要的时候这或许就帮到了你。本篇文章中代码实例可以在以下地址找到不要忘记为项目 star 哟https://github.com/newbe36524/Newbe.Demo/tree/main/src/BlogDemos/Newbe.StringPools
http://www.zqtcl.cn/news/51320/

相关文章:

  • 湖北天健建设集团有限公司网站内网wordpress响应慢
  • 郑州营销网站托管公司哪家好甘肃制作网站
  • 寻找杭州做网站软件人wordpress底部链接修改
  • 新洲城乡建设局网站杭州网站搜索
  • 黄埔网站建设网站建设计划书模板
  • 网站会员充值做哪个分录wordpress 空间推荐
  • 浙江省旅游企业网站建设情况做网站的背景图片格式大小
  • 十大设计创意网站重庆汉沙科技做网站怎么样
  • 华为官方网站进入称心的常州网站建设
  • 苏州网站建站推广wordpress em
  • 二级域名解析网站专业做物业网站的公司吗
  • 做暧暖ox网站给企业做网站多少钱
  • 列举电子商务网站建设需要的语言网站建设与管理课件
  • 如何破解网站后台密码有哪些网站可以做推广包包
  • 许昌做网站汉狮网络程序员 做网站 微信公众号 赚钱
  • 丽江古城区建设局网站达内网络营销
  • 做网站多少钱西宁君博示范打开官方网站
  • wordpress头像怎么修改优化营商环境条例解读
  • 只做网站应该找谁开发公司质量管理制度模板
  • 廊坊seo优化排名一键优化是什么意思
  • 网站建设类工作描述阿里云备案域名
  • SEO做得最好的网站如何做网站定位
  • 苏州高端网站设计制作买了个区域名怎么做网站
  • 天津市建设厅官方网站有没有哪些可以看片的
  • 上海网站建设市场产品推广网站排名
  • 百度是不是门户网站宝应网站
  • 网站图标怎么上传安徽建设工程信息网安全三类人员考试成绩查询
  • iis7建立网站墨子学院网站建设vip课程
  • 制作网站开发多少钱做网站公司 陕西渭南
  • 怀化网站定制互联网挣钱新方法