提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|行业资讯|编辑:蒋永|2016-11-24 10:24:40.000|阅读 217 次
概述:Martin Thompson是LMAX的联合创始人,在QCon圣保罗2016上做过关于性能的keynote演讲。他最初计划的演讲题目为“关于性能的神话与传说”,不过Thompson后来将演讲命名为“十大性能错误”,因为“我们都会犯错误,而且很容易就会出现错误”。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
Martin Thompson是LMAX的联合创始人,在QCon圣保罗2016上做过关于性能的keynote演讲。他最初计划的演讲题目为“关于性能的神话与传说”,不过Thompson后来将演讲命名为“十大性能错误”,因为“我们都会犯错误,而且很容易就会出现错误”。
下面列出了他在生产环境下所见到的性能错误TOP10,并且还包含了如何避免的建议。
很多人抱怨他们的系统不够快,并通过编写更好的算法和数据结构来寻求帮助,Thompson认为实际上“他们所需的仅仅就是进行升级”。升级操作系统、JVM、CLR等等。不进行升级的常见借口就是“在新版本中可能会有bug。”
为了避免这种状况,可以进行定期的持续集成和测试,这应该是开发流程的基础组成部分。Thompson以一个实时系统进行了例证,开发人员针对新版本的数据库进行了测试,在所有的测试通过之后,他们就将其发布到了生产环境之中。
Thompson讲述了某个系统的故事,这个系统是用来提供Web页面的,它非常缓慢,开发人员最初认为是数据库的问题并试图在这方面进行调优。但是当他在系统上运行profiler时,发现在一个循环中,ORM被调用了7,000次,这才是页面加载缓慢的罪魁祸首。当这个循环的问题修复之后,系统的响应变得完全正常。这里学到的经验就是“对系统进行度量。如果系统是一个黑盒的话,你就无法说明时间都耗费在了哪里。”
Thompson展现了一个基准测试结果,它会执行一项操作,该操作会对内存(RAM)中1GB数组的所有long型进行求和。这里所耗费的时间取决于内存是如何访问的,如下面的表格所示:
这个基准测试的结果显示并非所有的内存操作都是等价的,我们需要关注它是如何进行处理的。Thompson认为非常重要的一点在于了解各种数据结构的性能,他指出对于2GB以上的场景,Java的HashMap要比.NET的Dictionary慢十倍以上。他还补充说,也有一些场景.NET要比Java慢得多。
尽管在很多场景中,内存分配几乎是没有什么成本的,但是它们的回收却并非如此,因为在面对大量的数据集时,垃圾收集器需要更多的时间。当分配大量的数据时,缓存会被填满,较旧的数据会被舍弃,使得在数据操作上的效率变为90ns/op而不是7ns/op,这里变慢了不止一个数量级。
尽管对于特定的算法来说,采用并行很有吸引力,但是它也有一些局限性和相关的开销。Thompson引用了“可扩展性!但是其COST如何?”这篇论文,论文的作者通过引入COST(胜过单线程的配置,Configuration that Outperforms a Single Thread)对比了并行系统以及单线程的系统,COST的定义如下:
在特定的平台中,特定问题的COST指的是优于单线程方案所需的硬件配置。COST将系统的扩展性与系统所引入的开销进行了权衡,并指明了系统实际所能取得的性能,它们可能并没有带来实际的收益,却增加了并行所引入了开销。
作者分析了各种数据并行系统的测量结果,并得出如下的结论:“很多的系统要么具有非常高的COST,通常会需要上百个核心,要么针对他们所报告的配置,其性能要比单线程方案更差。”
在这个话题中,Thompson指出,并行任务会有相关的通信和同步开销,并且有些活动本质上要求是串行的,不能实现并行。按照Amdahl定律,如果系统中有5%的活动需要串行,那么不管使用了多少个处理器,系统的速度提升最多只能达到20倍。
Thompson还提到了Neil J. Gunther在1993年所提出的通用可扩展性定律(Universal Scalability Law,PDF),该定律指出在并行非共享系统(shared-nothing)中甚至会存在更多的局限性,当所使用的处理器数量达到一定程度后,速度会出现下降,这取决于并发、竞争以及同步的水平。(更多的细节可以参考如何量化可扩展性这个页面。)按照上述两个规律所总结的速度与处理器数量之间的关系如下图所示:
Thompson指出通过USL能够看到性能的下降,这要归因于并行系统中组件之间进行通信所消耗的成本:“在系统中,所投入资源越多,通信路径也会随之增多,这会使算法的效率降低。”
Thompson补充说,在构建并行系统时,主要的建议是避免共享可变(mutable)的状态,因为“它非常难以进行判断……最终你会遇到很多的bug”。推荐的方式是要么采用非共享架构,要么针对特定的一块数据,只使用一个写入器。
对这个性能问题,他的最终建议:如果你想提升算法的速度的话,在尝试并行方案之前,先设法提升单线程版本的性能,因为并行方案实在是太难了。
针对这个话题,Thompson认为很多在考虑微服务架构的人对TCP并没有充分的理解。在特定的场景中,有可能会遇到延迟的ACK,它会限制链路上所发送的数据包,每秒钟只会有2-5个数据包。这是因为TCP两个算法所引起的死锁:Nagle以及TCP Delayed Acknowledgement。在200-500ms的超时之后,会打破这个死锁,但是微服务之间的通信却会分别受到影响。推荐的方案是使用TCP_NODELAY,它会禁用Nagle的算法,多个更小的包可以依次发送。按照Thompson的说法,其中的差别在5到500 req/sec。
客户端和服务器之间的同步通信会带来时间的损耗,对于需要快速通信的系统来说,这会成为一个问题。Thompson说,它的解决方案并不是购买更加昂贵和快速的硬件,而是使用异步通信。在这种场景下,客户端可以发送多个请求到服务器端,而不必等待它们之间的响应。采用这种方式需要改变客户端发送请求的方式,但这是值得的。
开发人员很多时候会选择使用文本编码格式实现链路上的数据传输,比如JSON、XML或Base64,因为“这对人类是可读的”。但是Thompson指出在两个系统之间进行对话的时候,是没有人读这些数据的。借助这种方式,使用简单的文本编辑器就能很容易地进行调试,但是在将二进制数据与文本之间进行互相转换的时候,这会带来很高的CPU损耗。该问题的解决方案是使用能够理解二进制的更好的工具,Thompson提到了Wireshark。
按照Thompson的说法,有一些与性能相关的最负面影响是由API引起的。它使用如下的代码来阐述较差的代码签名:
public void startElement( String uri, String localName, String qName, Attributes atts) throws SAXException
描述:
在处理XML的时候,通常我们并不会使用这些值[三个String以及属性的集合]。我们分配了很多的内容,但是却将其浪费并抛弃掉了。这会损耗电池的寿命,白白地浪费资源。我们需要使其更加简单一些。
他建议采用如下的签名,实现更加简单的方法:
public void characters( char[] ch, int start, int length) throws SAXException
有些人可能会抱怨后面的这个方法要比前一个更难用,Thompson建议采用组合的方式,将其中一个用另一个封装起来,这样的话,能够给用户多一个选择。如果性能不是什么问题的话,可以采用第一种(使用String),否则的话,第二个方案会更好一些。
Thompson提到的第二个样例是字符串拆分:
public String[] split(String regex)
这个方法签名相关的性能问题包括:
更好的方案是使用Iterable,它能够避免在内存中创建中间状态的token副本:
public Iterable split(String regex)
另外一种方案是允许调用者提供存储token的集合。如果调用者想要对token列表去重的话,应该传递一个Set进来,如果想得到有序列表的话,就需要传递一个TreeMap进来:
public void split( String regex, Collection dst)
Thompson所列的排名第一的性能问题是写日志所耗费的时间。他通过一个图表展现了当线程数增加的时候,日志操作所耗费的平均时间:
这个图显示了一个100%的顺序操作,不管使用多少线程来记录日志,所需的时间均呈线性增长。Thompson说大多数已有的日志系统都可以得出这样一幅图表,“Logger是系统中最大的瓶颈之一”。这个问题的解决方案是使用异步的Logger。
另外,Logger所记录的数据应该是结构化的数据,便于后续的工具进行读取和处理,而不应该是一堆String。如果是记录重复的错误,他建议在错误第一次出现的时候进行记录,后续出现时只需对一个计数器进行递增,告知对应的错误出现了多少次即可。对于实时系统的调试,Thompson建议使用代码编织(code weaver)的技术,如Byte Buddy,因为它能够避免编写和运行不必要的日志代码。
活动时间:11月1日-11月30日
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
通过提供强大的3D CAD数据访问工具并适用于桌面、移动和Web的高级环境3D可视化发动机,HOOPS在提升造船设计和制造流程的效率方面发挥了重要作用。
HOOPS Luminate在汽车行业中的应用具有广泛的潜力和深远的影响。它通过提供高效的3D可视化、虚拟装配与拆解、性能分析、客户定制等功能,帮助汽车制造商在设计、生产和销售过程中提升效率、降低成本并提高产品质量。
在不断发展的软件开发世界中,使工具和框架与最新的平台版本保持同步至关重要,欢迎查阅~
全球航运业对国际贸易至关重要,全球 90% 以上的商品通过海运运输。准确监控和控制这些集装箱的移动对于维持高效的供应链至关重要。手动输入集装箱号码是这一程序的关键部分,它带来了相当大的挑战,例如人为错误和效率低下。
人工智能和机器学习赋能 API 和 Web 服务测试
LoadRunnerLoadRunner是一款负载测试软件,可使您精确洞察端到端系统性能,以便在应用正式推出之前识别和解决其中的问题。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢