请看一个测试:
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确实是系统瓶颈很重要的一个原因。
相关推荐
性能瓶颈是指在特定条件下限制系统性能的关键因素。这些瓶颈可能会随时间发生变化或转移,例如随着站点访问量的增长,瓶颈可能会从服务器处理能力转移到数据库查询性能等方面。 - **网络传输瓶颈**:当大量用户同时...
1.1 等待的真相 1.2 瓶颈在哪里 1.3 增加带宽 1.4 减少网页中的HTTP请求 1.5 加快服务器脚本计算速度 1.6 使用动态内容缓存 1.7 使用数据缓存 1.8 将动态内容静态化 1.9 更换Web服务器软件 1.1 页面组件...
1.1 等待的真相 1.2 瓶颈在哪里 1.3 增加带宽 1.4 减少网页中的HTTP请求 1.5 加快服务器脚本计算速度 1.6 使用动态内容缓存 1.7 使用数据缓存 1.8 将动态内容静态化 1.9 更换Web服务器软件 1.10 页面组件...
1.1 等待的真相 1.2 瓶颈在哪里 1.3 增加带宽 1.4 减少网页中的HTTP请求 1.5 加快服务器脚本计算速度 1.6 使用动态内容缓存 1.7 使用数据缓存 1.8 将动态内容静态化 1.9 更换Web服务器软件 1.1 页面组件...
- 安装监控工具,如Prometheus和Grafana,收集和展示系统性能指标。 - 设置日志记录,便于排查问题和分析性能瓶颈。 9. **故障转移与容错**: - 当某个Tomcat实例宕机时,Nginx应能自动将流量重定向至其他正常...
4. 分析AWR报告中的各项指标,寻找性能瓶颈。 **示例命令**: ```sql -- 登录到Oracle数据库 # su – oracle -- 创建AWR快照 exec dbms_workload_repository.create_snapshot; -- 获取AWR快照数据 exec dbms_...
1. **实时监控**:通过实时展示系统性能、网络流量、应用健康状况等关键指标,运维人员能够及时发现并响应问题,减少故障发生。 2. **流程优化**:可视化可以清晰地展示代码部署、测试和发布的过程,帮助企业识别...
4. **性能分析**:工具库可能包含性能分析工具,用于检测程序瓶颈,优化代码。 5. **文档和教程**:通常附带详细的用户手册和学习资源,帮助初学者快速上手。 **Prolog的应用** Prolog的逻辑编程特性使其在以下...
7. **性能分析**:使用cProfile或timeit模块,可以分析代码的运行时间和性能瓶颈,从而优化代码。 综上所述,"什么是真的"在Python开发中意味着验证和维护代码的正确性、可读性、可维护性和性能。通过遵循最佳实践...