部分转载[C#性能优化实践]
全文出处:http://www.infoq.com/cn/articles/C-sharp-performance-optimization
1.性能
主要指两个方面:内存消耗和执行速度。性能优化简而言之,就是在不影响系统运行正确性的前提下,使之运行地更快,完成特定功能所需的时间更短。
2.理解瓶颈
99%的性能消耗是由于1%的代码造成的。大部分性能优化都是针对这1%的瓶颈代码进行的。具体实施也就分为两步:“发现瓶颈”和“消除瓶颈”。
3.切忌过度
性能优化本身是有成本的。这个成本不单单体现在做性能优化所付出的工作量,还包括为性能优化而写出复杂的代码导致额外的维护成本,比如引入新的Bug,额外的内存开销等。性能优化常常需要在收益和成本之间做出权衡。
4.如何发现性能瓶颈
性能优化的第一步是发现性能瓶颈,下面是一些定位性能瓶颈的实践。
A.如何获取内存消耗
以下代码可以获取某个操作的内存消耗:
long start = GC.GetTotalMemory(true);
// 在这里写需要被测试内存消耗的代码,例如,创建一个GcMultiRow
var gcMulitRow1 = new GcMultiRow();
GC.Collect();
// 确保所有内存都被GC回收
GC.WaitForFullGCComplete();
long end = GC.GetTotalMemory(true);
long useMemory = end - start;
B.如何获取时间消耗
以下代码可以获取某个操作时间消耗:
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Start();
for (int i = ; i < ; i++)
{
gcMultiRow1.Sort();
}
watch.Stop();
var useTime = (double)watch.ElapsedMilliseconds / ;
----为了获得更加稳定的时间消耗,这里把一个操作循环执行了1000次,取时间消耗的平均值以排除不稳定数据。
5.性能优化的方法和技巧
A.优化程序结构
B.缓存
缓存(Cache)是性能优化中最常用的手段,针对需要频繁的获取一些数据,同时每次获取数据需要的时间比较长的场景。如果使用了缓存的优化方法,需要特别注意缓存数据的同步:如果真实的数据发生了变化,应该及时的清除缓存数据,确保不会因为缓存而使用了错误的数据。使用缓存的情况比较多, 最简单的情况就是缓存到一个Field或临时变量里。
for(int i = ; i < gcMultiRow.RowCount; i++)
{
// Do something;
}
以上代码一般情况下是没有问题的,但是,如果GcMultiRow的行数比较大。而RowCount属性的取值又比较慢的时候,就需要使用缓存来做性能优化。
int rowCount = gcMultiRow.RowCount;
for (int i = ; i < rowCount; i++)
{
// Do something;
}
C.延迟加载
大多时候,对于创建需要花费较长时间的对象,往往并不是所有的场景下都需要使用。这时,使用懒构造的方法可以有效提高程序启动性能。
举例来说,对象A需要内部创建对象B。对象B的构造时间比较长。 一般做法:
public class A
{
public B _b = new B();
}
一般做法下,由于构造对象A的同时要构造对象B,导致A的构造速度也变慢了。
优化做法:
public class A
{
private B _b;
public B BProperty
{
get
{
if(_b == null)
{
_b = new B();
}
return _b;
}
}
}
优化后,构造A的时候就不需要创建B对象,有效的提高了A的构造性能。
D.优化算法
E.正确的使用既有数据结构
.NET平台有很多现成的数据结构。我们应该了解这些数据结构,提升我们程序的性能。
例如:
1. String的加运算符和StringBuilder:
字符串的操作是我们经常遇到的基本操作之一。 我们经常会写这样的代码 string str = str1 + str2。当操作的字符串很少的时候,这样的操作没有问题。但是如果大量操作的时候(例如文本文件的Save/Load, Asp.net的Render),这样做就会带来严重的性能问题。这时,我们就应该用StringBuilder来代替string的加操作。
2. Dictionary 和 List:
Dictionary和List是最常用的两种集合类。选择正确的集合类可以很大的提升程序的性能。为了做出正确的选择,我们应该对Dictionary 和List的各种操作的性能比较了解。 下表中粗略的列出了两种数据结构的性能比较。
操作 List Dictionary 索引 快 慢 Find(Contains) 慢 快 Add 快 慢 Insert 慢 快 Remove 慢 快
3.TryGetValue: 对于Dictionary的取值,比较直接的方法是如下代码:
if(_dic.ContainKey("Key")
{
return _dic["Key"];
}
当需要大量取值的时候,这样的取法会带来性能问题。优化方法如下
object value;
if(_dic.TryGetValue("Key", out value))
{
return value;
}
后一种用法要比前一种用法取值性能提高一倍。
4. 为Dictionary选择合适的Key:
Dictionary的取值性能很大情况下取决于做Key的对象的Equals和GetHashCode两个方法的性能。如果可以的话,使用Int做Key性能最好。如果是一个自定义的Class做Key的话,最好保证以下两点:
1)不同对象的GetHashCode重复率低。
2)GetHashCode和Equals方法简单,效率高。
5. List的Sort和BinarySearch性能很好,如果能满足功能需求,推荐直接使用。
List<int> list = new List<int>{, , };
list.BinarySearch(); // 对于存在的值,结果是1
list.BinarySearch(); // 对于不存在的值,会使用负数表示位置,
// 如查找8时,结果是-2, 查找0结果是-1,查找100结果是-4.
部分转载[C#性能优化实践]的更多相关文章
- 让Elasticsearch飞起来!——性能优化实践干货
原文:让Elasticsearch飞起来!--性能优化实践干货 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog ...
- 直播推流端弱网优化策略 | 直播 SDK 性能优化实践
弱网优化的场景 网络直播行业经过一年多的快速发展,衍生出了各种各样的玩法.最早的网络直播是主播坐在 PC 前,安装好专业的直播设备(如摄像头和麦克风),然后才能开始直播.后来随着手机性能的提升和直播技 ...
- 手游录屏直播技术详解 | 直播 SDK 性能优化实践
在上期<直播推流端弱网优化策略 >中,我们介绍了直播推流端是如何优化的.本期,将介绍手游直播中录屏的实现方式. 直播经过一年左右的快速发展,衍生出越来越丰富的业务形式,也覆盖越来越广的应用 ...
- 转:携程App的网络性能优化实践
http://kb.cnblogs.com/page/519824/ 携程App的网络性能优化实践 受益匪浅的一篇文章,让我知道网络交互并不是简单的传输和接受数据.真正的难点在于后面的性能优化 下面对 ...
- Lazy<T>在Entity Framework中的性能优化实践
Lazy<T>在Entity Framework中的性能优化实践(附源码) 2013-10-27 18:12 by JustRun, 328 阅读, 4 评论, 收藏, 编辑 在使用EF的 ...
- Redis各种数据结构性能数据对比和性能优化实践
很对不起大家,又是一篇乱序的文章,但是满满的干货,来源于实践,相信大家会有所收获.里面穿插一些感悟和生活故事,可以忽略不看.不过听大家普遍的反馈说这是其中最喜欢看的部分,好吧,就当学习之后轻松一下. ...
- Tree-Shaking性能优化实践 - 原理篇
Tree-Shaking性能优化实践 - 原理篇 一. 什么是Tree-shaking 先来看一下Tree-shaking原始的本意 上图形象的解释了Tree-shaking 的本意,本文所说的前 ...
- Hadoop YARN:调度性能优化实践(转)
https://tech.meituan.com/2019/08/01/hadoop-yarn-scheduling-performance-optimization-practice.html 文章 ...
- Go RPC 框架 KiteX 性能优化实践 原创 基础架构团队 字节跳动技术团队 2021-01-18
Go RPC 框架 KiteX 性能优化实践 原创 基础架构团队 字节跳动技术团队 2021-01-18
随机推荐
- SDWebImage源码阅读-第一篇
一 题外话 之前写过一篇最新版SDWebImage的使用,也简单的介绍了一下原理.这两天正梳理自己的知识网络,觉得有必要再阅读一下源码,一是看具体实现,二是学习一下优秀开源代码的代码风格,比如接口设计 ...
- Asp.Net Core-----简介与安装
Asp.Net Core简介 ASP.NET Core 是一个全新的开源.跨平台框架,可以用它来构建基于网络连接的现代云应用程序,比如:Web 应用,IoT(Internet Of Things,物联 ...
- 请教 C# 异步 async await 问题
各位园友,之前对C#异步只是肤浅了解,请教一个具体问题. 需求: 前台会发送一个Array,这个数组都是 id的集合,比较大.分两步,首先保存这些id,然后去调用异步方法. 可以正常返回json,也可 ...
- 【麦克风阵列增强】Delay and sum beamforming
作者:桂. 时间:2017-06-03 15:40:33 链接:http://www.cnblogs.com/xingshansi/p/6937576.html 前言 本文主要记录麦克风阵列的几个基 ...
- 使用JPA和Hibernate进行批量处理的最佳方式
Tips 原文作者:Vlad Mihalcea 原文地址:The best way to do batch processing with JPA and Hibernate 在本文中,你将了解什么是 ...
- Bash命令行编辑
1.Readline库和命令行编辑 bash shell提供了两个内置编辑器:emacs和vi,利用它们可以以交互模式对命令行列表进行编辑,这项特性是通过Readline库的软件包实现的.当使用命令行 ...
- 为什么多线程、junit 中无法使用spring 依赖注入?
为什么多线程.junit 中无法使用spring 依赖注入? 这个问题,其实体现了,我们对spring已依赖太深,以至于不想自己写实例了. 那么到底是为什么在多线程和junit单元测试中不能使用依赖注 ...
- Vue按需加载提升用户体验
Vue官方文档异步组件: 在大型应用中,我们可能需要将应用拆分为多个小模块,按需从服务器下载.为了让事情更简单, Vue.js 允许将组件定义为一个工厂函数,动态地解析组件的定义.Vue.js 只在组 ...
- 关于java反射获取泛型
public class Test<T> { private final TypeToken<T> typeToken = new TypeToken<T>(get ...
- 记一次linux主机名莫名其妙变成了bogon
起因:公司网络接口做了接口认证,虚拟机桥接至物理网卡无法完成认证进行网络访问,无奈之下只能讲虚拟机网络模式更改为NAT模式,更改完成之后进行ssh登录,发现主机名发生了变化. 更改NAT模式之前 [r ...