请看一个测试:
1、快速排序100次,然后计算排序一次所需要的时间。
public QuickSort() { long beginTime = System.nanoTime(); //排100遍 int b[]=a.clone(); for(int i=0;i<100;i++){ quick(b); } long total = System.nanoTime() - beginTime; //18133 System.out.println("小数组快速排序所需平均时间:" + total/100); }
在我的机器上,大概时间是:
小数组快速排序所需平均时间:18133
2、计算使用system.out.println打印一个字符串使用的时间:
public static void main(String[] args) { long beginTime = System.nanoTime(); for(int i=0;i<100;i++){ System.out.println("hello World"); } long total = System.nanoTime() - beginTime; /** * 18214 */ System.out.println("平均每次磁盘IO时间:" + total/100); }
打印时间大概是:
平均每次磁盘IO时间:18334
3、记录从局域网的机器上获取一个数据所需要的时间,我们使用虚拟机的memcached作为测试对象。
public class MemcachedTest { private MemcachedClient memCachedClient ; MemcachedTest() throws IOException{ memCachedClient = new MemcachedClient( new InetSocketAddress("192.168.1.103", 11211)); } public static void main(String[] args) throws IOException { new MemcachedTest().test(); } private void test() throws IOException { long beginTime = System.nanoTime(); for(int i=0;i<100;i++){ memCachedClient.get("dfsdf" + i); } long totalTime = System.nanoTime()-beginTime; //计算平均时间,这里抹掉了小数点,平均:516486 System.out.println("从局域网的memcached取一次数据所需平均时间:" + (totalTime/100)); } }
打印时间:
从局域网的memcached取一次数据所需平均时间:528065
其实测试1是计算机最擅长的操作,通常这个操作在计算机的内存进行,测试2操作其实是一个IO操作,会涉及到一个向显卡写数据的IO,第三个操作,其实是一个网络IO,计算机会向网卡发送一个指令,到另外一条机器接收到命令,最后再从网卡读结果。
最后得出,各时间大概有如下关系:
快速排序≈一次磁盘IO≈1/29memcached所需要的时间。
可以看出,系统中一旦发生IO,其所需的时间通常比直接操作内存慢好几百倍,因为一个快速排序,会有好几百次的数据移动和比较。对于经过网络的操作,通常其速度又会比磁盘慢至少一个数量级。
尽管现在各种分布式产品很流行,但是这些基础常识,还是应该牢记在心,这样才能够写出高效率,高稳定性的软件。下面是我总结出的代码中几条涉及到性能的几条准则:
一、能够在内存解决的尽量不要访问磁盘,能在本机磁盘解决的,尽量不要访问网络。
二、多线程并发访问程序中,能不共享数据的尽量不要共享(StringBuilder优于StringBuffer);能够使用并发工具类(Atomic相关类,ConcurrentHashMap,CAS等)的,尽量不要使用synchronized。
三、在访问数据库时,对于常用的查询条件一定要建好复合索引。能够不排序的尽量不要排序,如果需要排序的,一定把排序字段提前存好,而不要在查询的时候再计算排序字段。
四、批量优于单个操作,很多产品,比如数据库,memcached等,都有批量及单个操作。在一些任务类中,如果能够批量操作,则优先使用批量接口。
五、某些计算时间长(比如用户要导出大文件)的操作,尽量进行优化。如果系统中必须存在这样的操作,那就用队列来专门解决这些问题,一定要控制系统线程的数量。
另外,在项目中,大多数系统的瓶颈可能都在数据库,通常,如果一个系统的用户超过1w,缓存就非常必要了。其实,性能问题,不仅仅出在代码级别,还有可能是在中间件上发生,比如apache的默认配置,就非常不适合大的并发系统,mysql的缓存,oracle的最大连接数等等,甚至前段的JS加载及运行,都可能带来性能问题。精通一些中间件,同样可以提高系统的性能和吞吐量。
通常性能都是在用户使用时才被发现,因此,排查问题比较困难。关于他的话题,写出好几本书也阐述不完,在这里,写的标题有点夸张,但是,不可置疑,软件中的IO确实是系统瓶颈很重要的一个原因。
相关推荐
找出系统性能瓶颈:企业级系统性能分析实践 v3.0.pdf
性能测试中如何定位性能瓶颈,对一些常见衡量CPU,内存,磁盘的性能指标,进行综合分析,然后根据所测系统具体情况,进行初步问题定位,然后确定更详细的监控指标来分析。
“软件系统性能检测与瓶颈分析”是中国软件测评中心培训内容
MOMO陌陌高永芝在2017PHP全球开发者大会上做了主题为《复杂PHP系统性能瓶颈排查及优化》的演讲,就PHP系统数据筛选及统计,可视化性能指标,搞笑优化方案做了深入分析。
找出系统性能的瓶颈:企业级系统性能分析实践
各类服务器性能瓶颈分析 各类服务器性能瓶颈分析 各类服务器性能瓶颈分析
* 轻松发现和消除性能瓶颈 * 查找问题代码 * 节省后续硬件及开发投入 * 增加应用发布信心 * 与开发过程集成,改善应用性能 JProbe Suite是一种能节省开发时间、降低开发费用、改善Java应用运行速度及和扩展能力的...
使用JProfiler结合LoadRunner寻找系统性能瓶颈
一款能分析系统性能瓶颈的优化软件。它通过对系统全方位的诊断,找到系统性能的瓶颈所在,然后有针对性地进行修改、优化。此外它还具有间谍软件和恶意软件扫描清除功能,也能将你的隐私信息从电脑中抹除。
JAVA性能瓶颈和漏洞检测工具
常见Web性能瓶颈及分析.pdf
Linux实时性能瓶颈分析.pdf
BOSS数据库系统性能瓶颈分析和定位.pdf
进行优化,先得找到性能瓶颈
性能瓶颈分析方法,一个很好的性能瓶颈分析方法,一个很好的性能瓶颈分析方法,
该文档介绍了在性能测试中一个很重要的阶段,分析结果阶段中如何分析系统的瓶颈所在,是初中级性能测试人员的最佳学习文档
利用Windows性能计数器分析软件产品的性能瓶颈归纳.pdf
文章对服务器可能的性能瓶颈给出了大概分析,对于常见性能问题比较有帮助,有兴趣的可以看看