ImageVerifierCode 换一换
格式:PDF , 页数:69 ,大小:782.29KB ,
资源ID:7352    下载:注册后免费下载
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.wenkunet.com/d-7352.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(.NET平台代码性能优化的几点建议(z).pdf)为本站会员(李静文)主动上传,文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知文库网(发送邮件至13560552955@163.com或直接QQ联系客服),我们立即给予删除!

.NET平台代码性能优化的几点建议(z).pdf

1、.NET 性能优化的几点建议 赵 劼 2017.10成功者都在高价值区努力 专注于高价值技术资料分享 高端技术圈自我介绍 赵劼 / 赵姐夫 / Jerey Zhao 2011 年前:互联网 2011 年起:IBM / JPMorgan Chase string Concat(string a, string b, string c, string d) return new StringBuilder() .Append(a).Append(b) .Append(c).Append(d) .ToString(); 字符串拼接与StringBuilder string Concat(int n,

2、 string a, string b, string c, string var s = “; for (var i = 0; i !dumpheap -stat MT Count TotalSize Class Name . 000007fef5c1fca0 5 120 System.Object . !dumpheap -mt 000007fef5c1fca0 Address MT Size 0000000002641408 000007fef5c1fca0 24 00000000026428a8 000007fef5c1fca0 24 0000000002642f48 000007fe

3、f5c1fca0 24 0000000002642f80 000007fef5c1fca0 24 0000000002645038 000007fef5c1fca0 24获取对象尺寸 优点:使用简单,包含对齐信 息。 缺点:丢失细节,包含额外对 象。 var currentBytes = GC.GetTotalMemory(true); var obj = new object(); / Or other types var objSize = GC.GetTotalMemory(true) - currentBytes; Console.WriteLine(objSize); / Outpu

4、t: / 12 in x86 / 24 in x64 GC.KeepAlive(obj);引用类型对象布局 class Person private readonly long _id; private readonly string _name; 引用类型对象尺寸 class MyType1 int Field1; / addr+8, 4 bytes / 24 bytes class MyType2 int Field1; / addr+8, 4 bytes int Field2; / addr+12, 4 bytes / 24 bytes class MyType3 int Field1;

5、 / addr+8, 4 bytes string Field2; / addr+16, 8 bytes (alignment) / 32 bytes基础类型数组尺寸 new int0; / 24 bytes (8 header + 8 MT + 4 length + 4) new int9; / 64 bytes (24 + 4 * 9 + 4) new int10; / 64 bytes (24 + 4 * 10) new int11; / 72 bytes (24 + 4 * 11 + 4) new byte8; / 32 bytes (24 + 1 * 8) new byte9; /

6、32 bytes (24 + 1 * 9 + 7) new bool1; / 32 bytes (24 + 1 * 1 + 7) new bool2; / 32 bytes (24 + 1 * 2 + 6) . new bool8; / 32 bytes (24 + 1 * 8) new string0; new string5; / ?自定义值类型数组尺寸 struct MyStruct bool Field1; / 1 bit int Field2; / 4 bytes bool Field3; / 1 bit new MyStruct3; / 64 bytes (24 + X * 3)

7、= X = 12? !do 0000000002682e38 . Fields: MT Field Offset Type . Name . 400004a 8 System.Boolean . Field1 . 400004b c System.Int32 . Field2 . 400004c 10 System.Boolean . Field3自定义值类型数组尺寸 StructLayout(LayoutKind.Auto) struct MyStruct bool Field1; / 1 bit int Field2; / 4 bytes bool Field3; / 1 bit new

8、MyStruct3; / 48 bytes (24 + 8 * 3) !do 0000000002932e38 . Fields: MT Field Offset Type . Name . 400004a c System.Boolean . Field1 . 400004b 8 System.Int32 . Field2 . 400004c d System.Boolean . Field3如何改进? class MyItem static IEnumerable GetItems() / . / Initialization var allItems = GetItems().ToArr

9、ay(); / Iteration foreach (var item in allItems) / do something with item class MyItem MyItem Next; / Initialization MyItem head = null; foreach (var item in GetItems() head = new Item Next = head ; Reverse(head); / optional / Iteration for (var item = head; item != null; item = item.Next) / do some

10、thing with item 改进后 节省内存(可忽略)、无大对象(重要) 指令少:少一层间接访问,无数组越界检 查 布局紧凑:CPU 缓存利用得当延伸:双向链表 abstract class InplaceLinkedListNode where T : InplaceLinkedListNode T Prev; T Next; / or interface class InplaceLinkedList where T : InplaceLinkedListNode class MyItem : InplaceLinkedListNode 延伸:二叉树 abstract class In

11、placeBinaryTreeNode where T : InplaceBinaryTreeNode T Left; T Right; int Size; / or interface class InplaceAvlTree where T : InplaceBinaryTreeNode class MyItem : InplaceBinaryTreeNode 二:迎合GC 编程You might think that building a responsive .NET Framework app is all about algorithms, such as using quick

12、sort instead of bubble sort, but thats not the case. The biggest factor in building a responsive app is allocating memory, especially when your app is very large or processes large amounts of data. - Roslyn TeamGC in CLR vs. OpenJDK 缺点:配置选项少。 Workstation GC vs. Server GC Concurrent GC (Why disable?)

13、 优点:配置选项少,但对内存控制程度 高。 与其调整参数,不如迎合GC 编程 拥有更多避免内存分配的特性老生常谈:托管堆 Gen 0 :新对象,短期对象 Gen 1 :Gen 0 和Gen 2 之间的过 渡 Gen 2 :老对象,长期对象 回收:扫描,清理,压缩老生常谈:大对象堆(LOH ) 保存大于85K 的对象 随着Gen 2 回收而回收 回收:不压缩,容易产生碎 片 / Force compact once GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;特点 G

14、en 0 与Gen 1 :频率高,速度快 大对象堆与Gen 2 :频率低,速度慢 回收耗时只与存活对象数量有关 与已分配对象数量无关 避免少部分有用对象引用大量无用对 象 减少老代对象指向新代对象的引用如何避免垃圾回收 避免内存分配 绝大部分垃圾回收由内存分配引起 其他原因: 系统资源紧张、主动触 发 停止垃圾回收 / Suppress Gen 2 collection (Workstation only) GCSettings.LatencyMode = GCLatencyMode.LowLatency; / Suppress full (non-concurrent) Gen 2. GCS

15、ettings.LatencyMode = GCLatencyMode.SustainedLowLatency GC.TryStartNoGCRegion(.); / . No GC will happen here GC.EndNoGCRegion();例:获取CPU 使用率 / .NET 4.5.2- var cpuCounter = new PerformanceCounter( “Processor“, “% Processor Time“, “_Total“); for (var i = 0; i (int n) var tempArray = new Tn; / . abstrac

16、t class Buffer : IDisposable / array like operations public abstract T thisint i get; set; void DoSomethingNeedsTempArrayOfLength(int n) using (var tempBuffer = RequestBuffer(n) / . class StructBuffer : Buffer private readonly T _array; public override T thisint i get return _arrayi; set _arrayi = v

17、alue; class ClassBuffer : Buffer private readonly object _array; public override T thisint i get return (T)_arrayi; set _arrayi = value; 避免LOH 碎片 预分配,避免自适应分配,例 如 StringBuilder MemoryStream List 分配统一尺寸的对象,或 统一尺寸的整数倍理想中的对象生命周期 极短:分配后立即丢弃 不会被GC 扫描到 不会被提升至Gen 2 极长:分配后永不丢弃 快速提升至Gen 2 后永久保留,避免压 缩 分配至LOH 后

18、永久保留,避免碎片优化案例 class Order public int OrderId get; set; public string Side get; set; public double Price get; set; / 200+ more fields . / 1.2KB / 50000 instances max, 60M优化案例(结果) struct OrderData public int OrderId public string Side public double Price / 200+ more fields . / 1.2KB / 60M static Order

19、Data AllOrderData = new OrderData50000;优化案例(结果) struct Order private readonly int _index; public int OrderId get return AllOrderData_index.OrderId; set AllOrderData_index.OrderId = value; public string Side get return AllOrderData_index.Side; set AllOrderData_index.Side = value; . / zero in heap, 4

20、bytes in stack优化后 优点 更少的对象 更短的GC 扫描时间 永不涉及回收的对象 缺点 驻留内存较多 重用存储空间带来额外复杂 度延伸:双向链表 var list = new LinkedList(); for (var i = 0; i / . 16 bytes head . / Prev - 8 bytes / Next - 8 bytes / List - 8 bytes / Value - 4 bytes / . 4 bytes alignment . / / 48 bytes node to save 4 bytes data / nodes are everywher

21、e in heap延伸:双向链表 class ArrayLinkedList private Node _nodes; public struct Node public T Value; public int Next; public int Prev; / “index“ is node public int AddLast(T value) / 12 bytes to save 4 bytes data / nodes are kept closely (probably same cache line) in he延伸:二叉树 class ArrayAvlTree private No

22、de _nodes; public struct Node public T Value; public int Left; public int Right; public int Size; / “index“ is node public int Add(T value) 三、编写不通用的代码代码调用 public class MyClass MethodImpl(MethodImplOptions.NoInlining) public void NormalMethod() public virtual void VirtualMethod() void CallNormal(MyCl

23、ass c) c.NormalMethod(); void CallVirtual(MyClass c) c.VirtualMethod(); 代码调用(非虚方法) void CallNormal(MyClass c) c.NormalMethod(); 488bca mov rcx, rdx 3909 cmp rcx, ecx ; null check e8a2a4ffff call 00007ffe80c47b40 (MyClass.NormalMethod()代码调用(虚方法) void CallVirtual(MyClass c) c.VirtualMethod(); 488bca m

24、ov rcx, rdx 488b02 mov rax, rdx ; address of method table 488b4040 mov rax, rax+0x40 ; address of methods ff5020 call qword rax+0x20 ; address of target method集合 static ICollection CreateCollection(IEnumerable itemreturn name.ToList(); In Visual Studio and the new compilers, analysis shows that many

25、 of the dictionaries contained a single element or were empty. An empty Dictionary has ten fields and occupies 48 bytes on the heap on an x86 machine. Dictionaries are great when you need a mapping or associative data structure with constant time lookup. However, when you have only a few elements, y

26、ou waste a lot of space by using a Dictionary. - Roslyn Team集合创建(Roslyn ) static ICollection CreateReadOnlyMemberNames( HashSet names) switch (names.Count) case 0: return SpecializedCollections.EmptySet(); case 1: return SpecializedCollections.Singleton(names.Firstcase 26: return ImmutableArray.Crea

27、teRange(names); default: return SpecializedCollections.ReadOnlySet(names); return names.ToList(); FrugalList/Map in WPF class FrugalListBase class SingleItemList : FrugalListBase class ThreeItemList : FrugalListBase class SixItemList : FrugalListBase class ArrayItemList : FrugalListBase class Frugal

28、MapBase class SingleObjectMap : FrugalMapBase class ThreeObjectMap : FrugalMapBase class SixObjectMap : FrugalMapBase class ArrayObjectMap : FrugalMapBase class SortedObjectMap : FrugalMapBase class HashObjectMap : FrugalMapBase class LargeSortedObjectMap : FrugalMapBase 不通用的迭代器 class MyCollection :

29、 IEnumerable public struct MyEnumerator : IEnumerator / . public MyEnumerator GetEnumerator() / . IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); 不通用的迭代器 var coll = new MyCollection(); / has allocations: / 1. (IEnumerabl

30、e)coll).Where(.) / 2. anonymous method foreach (var i in coll.Where(i = i 0) / Do something / no allocation foreach (var i in coll) if (i 0) / Do something 简易IDisposable 实现 class MyClass private void Done(int i) / . public IDisposable DoSomething(int i) / . return Disposables.Create() = Done(i); / H

31、as allocations using (myClass.DoSomething(10) / Do something 不通用的IDisposable 实现 class MyClass public struct DoneToken : IDisposable private readonly MyClass _parent; private readonly int _i; public void Dispose() _parent.Done(_i); / no allocation public DoneToken DoSomething(int i) / . return new Do

32、neToken(this, i); 使用最新版本的C#/.NET ValueTask :轻量级Task ValueTuple :轻量级Tuple Span :泛化版的 String/ArraySegment ref return :安全地返回一个地址 readonly ref :按引用传递只读变量无ref return interface IMap TValue Get(TKey key); void Set(TKey key, TValue value); void Increase(IMap map, TKey key, int n) var value = map.Get(key); m

33、ap.Set(key, value + n); ref return interface IMap ref TValue GetRef(TKey key); void Increase(IMap map, TKey key, int n) map.GetRef(key) += n; 五、善用工具常备工具 WinDBG PerfView 某商业化CPU Profiler 某商业化Memory Profiler CLRMDCLRMD CLRRuntime runtime = .; GCHeap heap = runtime.GetHeap(); foreach (ulong obj in heap.EnumerateObjects() GCHeapType type = heap.GetObjectType(obj); if (type = null) / heap corruption continue; ulong size = type.GetSize(obj); Console.WriteLine( “0,12:X 1,8:n0 2,1:n0 3“, obj, size, heap.GetObjectGeneration(obj), type.Name)

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:文库网官方知乎号:文库网

经营许可证编号: 粤ICP备2021046453号世界地图

文库网官网©版权所有2025营业执照举报