首页 文章 精选 留言 我的

精选列表

搜索[官方镜像],共10000篇文章
优秀的个人博客,低调大师

阿里云容器服务cni网络插件terway非官方网络性能测试

作者:荣滨,酷划在线后端架构师,关注微服务治理,容器化技术,Service Mesh等技术领域 terway网络性能测试 酷划在线成立于2014年,是国内激励广告行业的领军者。酷划致力于打造一个用户、广告主、平台三方共赢的激励广告生态体系,旗下产品“酷划锁屏”“淘新闻”分别为锁屏、资讯行业的领跑者。 伴随着公司服务端架构向微服务演进的过程中,服务增多,运维成本提高,资源利用率低,等问题日益凸显,目前公司服务器规模超过700+台ECS,服务数量1000+,随着容器化技术的成熟,计划在近期大规模将生产环境迁移到阿里云容器服务平台上,但由于VxLan等主机转发模式的Overlay网络均有一定的性能损耗,所以我们将目光瞄准阿里云容器服务平台开源的terway网络插件,期望使用能够动态绑定弹性网卡的容器服务达到ECS的网络性能,进而对terway网络性能进行详细的评估。 测试说明 本测试基于阿里云容器服务Kubernetes版(1.12.6-aliyun.1),Kubernetes集群使用阿里云控制台创建,测试分两部分: 同可用区网络性能测试 跨可用区网络性能测试 本测试的所有网络流量均为跨节点通信(容器分布在不同的宿主机节点上)本测试的所有测试均穿插测试超过3组取结果平均值 关键指标 吞吐量(Gbit/sec) PPS(Packet Per Second) 延时(ms) 测试方法 吞吐量,PPS测试使用iperf3 版本信息如下: iperf 3.6 (cJSON 1.5.2) Linux iperf3-terway-57b5fd565-bwc28 3.10.0-957.5.1.el7.x86_64 #1 SMP Fri Feb 1 14:54:57 UTC 2019 x86_64 Optional features available: CPU affinity setting, TCP congestion algorithm setting, sendfile / zerocopy, socket pacing 测试机命令: # 启动服务器模式,暴露在端口16000,每1秒输出一次统计数据 iperf3 -s -i 1 -p 16000 陪练机命令: # 测试吞吐量 # 客户端模式,默认使用tcp通信,目标机为172.16.13.218,持续时间45,-P参数指定网卡队列数为4(跟测试的机型有关),目标端口16000 iperf3 -c 172.16.13.218 -t 45 -P 4 -p 16000 # 测试PPS # 客户端模式,使用udp发包,包大小为16字节,持续时间45秒,-A指定CPU亲和性绑定到第0个CPU iperf3 -u -l 16 -b 100m -t 45 -c 172.16.13.218 -i 1 -p 16000 -A 0 # 测试延迟 # ping目标机30次 ping -c 30 172.16.13.218 测试结果 同可用区网络性能测试 机型说明 测试机型选用ecs.sn1ne.2xlarge,规格详情如下 测试结果 说明:纵轴表达流量流出方向,横轴表达流量流入方向,所以组合情况一共有9种 名词解释: terway-eni:代表动态创建弹性网卡并绑定POD的terway网络模式 terway:代表默认的terway网络模式 结果解读 各种模式下均可将网卡带宽打满,从吞吐量上看结果无明显区别 从流量流入容器角度看数据,流向terway-eni模式在各项指标均接近甚至超过流向宿主机的性能 从流量流出容器角度看数据,terway-eni模式性能接近但略低于宿主机流量流出性能,但明显高于terway默认网络 跨可用区网络性能测试 测试机型选用ecs.sn1ne.8xlarge,规格详情如下 测试结果 说明:纵轴表达流量流出方向,横轴表达流量流入方向,所以组合情况一共有9种 名词解释: terway-eni:代表动态创建弹性网卡并绑定POD的terway网络模式 terway:代表默认的terway网络模式 结果解读 由于增加了跨可用区的调用,使影响结果的因素变多 host to host的吞吐量,并没有达到网卡的理论最大值,但是流入terway-eni的吞吐量基本达到了机型的带宽6 Gbit/sec,需要进一步调查宿主机间吞吐量上不去的原因 从容器流出的流量角度看,terway-eni模式整体明显高于terway默认网络模式,但低于宿主机网络性能 从流入容器的流量角度看,terway-eni的PPS结果数据优势比较明显,接近甚至超越宿主机网卡性能 总体结论 terway的网络性能测试中表现出了与宣传一致的性能,通过与作者的沟通中了解到,由于将弹性网卡直接放入POD的namespace内,虽然网卡驱动的中断依然由宿主机内核完成,但是网络包不会出现在宿主机namespace的网络栈,减少了宿主机的一层cni网桥转发及复杂路由的性能损失,这也是为什么在某些场景下超过宿主机网络栈性能的表现。

优秀的个人博客,低调大师

阿里官方python群开始正式招募啦,I want you !

刚刚过完节日的你是否依然还是不在状态,云栖社区的运营小编已经忙的不亦乐乎啦, 最近两周的直播已经安排上,接下来会陆续更新。。。。。。 近两周直播排期 直播主题:Python深度学习第二讲——数据增广 直播时间:2月15日20:00—21:00 课程大纲:1、基于python的深度学习应用大观;2、基于python的深度学习数据增广方法;3、python数据增广所用库及代码解析; 直播讲师:猫饼君,香港城市大学理学硕士,曾在南洋理工大学参加过机器学习算法相关项目,现任职计算机视觉算法工程师,专注于计算机视觉算法研究及应用落地。 直播主题:python基础学习——爬虫分享 直播时间:2月20日 直播讲师:罗攀,阿里特邀专家,林学的研究僧《从零开始学Python网络爬虫》《从零开始学Python数据分析》作者Python中文社区、Python爱好者社

优秀的个人博客,低调大师

看IFA官方如何解读IFA2015的大主题——智能互联

今年IFA的大主题是“智能互联”,而不仅仅是“智能家居”。 一年一度的IFA2015已经在德国柏林拉开帷幕,作为全球家电品牌的盛事,备受全球消费电子、家用电器和相关行业瞩目。今年,IFA给我们带来的是“智能互联”的大主题。一起来看看IFA执行总监Jens Heithecker是如何诠释这一主题。 一、电视在消费电子行业仍是“重头戏” 电视制造商在市场上仍然面临着挑战,竞争日趋激烈让制造商的利润承受压力。不过,在今年的IFA上人们再次看到,电视在消费电子行业仍然是关键,因为对几乎每个消费者来说电视仍然是主要的显示(出口)。今年IFA的大主题是“智能互联”,而不仅仅是“智能家居”,因此会有很多新设备和软件解决方案,这也是所有制造商都瞄准的市场。 二、“智能”遇上“互联”,更要小心对待 这是一个互联世界,当人们谈论智能、物联网和所有相关事物的时候,就更要小心对待。对消费者而言,“智能”意味着针对其需求的自动化解决方案。互联世界意味着消费者可以随时随地把图片和音乐传输到其他设备上;物联网则是智能和互联消费者世界的支柱。 三、TecWatch是IFA成功不可或缺的因素 IFA的TecWatch主题展览是未来科技的“风向标”,也是IFA成功的关键。TecWatch是为参与进来的研究者、工程师、开发者、年轻企业甚至初创企业专门设立的展示区域,全球的参与度也在不断提高。与此同时,专业观众对这一展区的兴趣也越来越浓。 四、IFA+峰会旨在洞悉技术的未来走向 众所周知,专业观众参展多是为了下一季度的生意。TecWatch可以预见当前产品在未来三到五年的发展趋势,而峰会可以预见当前市场上已经见到的产品和未来十到二十年的发展变化。所以也可以说,当前的产品在展厅里,未来技术在TecWatch,而远见者和思想领袖头脑中的未来趋势则在IFA+峰会。 爱因斯坦是一个很好的、广为人知的例子。早在上世纪20年代末,他在IFA演讲中表达了一些超前的想法。现在你还可以看到这篇演讲,如果你有时间通篇听下来,你仍会对他的想法感到印象深刻,即电子媒体拥有的能量与影响。但是我们在历史上有很多这样的里程碑。其中一个例子,是上世纪90年代MP3技术的首次展示,虽然在当时受到的关注不大。这是由弗劳恩霍夫发明的,这家公司也是Tecwatch展区长期合作伙伴之一。当时大多数人并没有意识到MP3会彻底改变娱乐、世界和媒体行业。 五、每年的IFA国际主题演讲都有看头 今年IFA主题演讲者中有一位是来自微软集团OEM事业部负责人尼克·帕克(Nick Parker)。当提到微软的时候,我们往往只想到Win10或其他新软件。但更有意思的是Win10会对微软合作伙伴制造的整个世界的设备带来的影响。这就是为什么IFA邀请微软OEM事业部负责人做主题演讲的原因。 不过,IFA还有其他的主题演讲同样吸引人,比如LG Display总裁兼CEO韩相范的开幕主题演讲。在讨论互联和智能世界的时候,开幕主题演讲聚焦显示技术。可以说这是一切的核心,因为没有显示,智能手机就算不得智能。在显示技术方面有很多新进展,我们可以听到这位富有远见的演讲者的真知灼见。 原文发布时间: 2015-09-06 19:17 本文作者: Berry 本文来自云栖社区合作伙伴镁客网,了解相关信息可以关注镁客网。

优秀的个人博客,低调大师

微软封杀IE10等旧版浏览器访问官方网页

【大咖・来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》 虽然你可能当时买了正版,虽然你怀念经典,但对于像微软这样的软件巨头来说,他们是很难容忍你坚守旧版,不升级新版的,所以,“高压”政策必不可少。 据 neowin 报道,微软发出警告,从 9 月 1 日开始,将不再允许版本号较老的浏览器访问企业商店。 因为遭封杀的名单实在太长,我们还是看看那些支持吧—— Microsoft Edge Internet Explorer 11, 2013 年发布 Google Chrome 22, 2012 年发布 Mozilla Firefox 27, 2013 年发布 Safari 7, 2013 年发布 iOS 5, 2011 年发布 很显然,预装了 Edge 和 IE11 的 Windows 10 潜移默化中成了“免死金牌”中的加冕者。 需要注意的是,微软企业商店(Company Store)是微软早期面向合作伙伴、内部员工的打折专区,但现在开放该了几乎所有网友,并且进化成了一个杂货铺,提供包括服装、饰品、文具等诸多品类产品。 当然,其实微软这么做也有自己的苦心,毕竟在安全形势越发不容乐观的当下,保证浏览器新版不仅可以获得较高的视觉体验,安全系数也高了。

优秀的个人博客,低调大师

官方文档】Nginx负载均衡学习笔记(二)负载均衡基本概念介绍

简介 负载均衡(Server Load Balancer)是将访问流量根据转发策略分发到后端多台 ECS 的流量分发控制服务。负载均衡可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 负载均衡主要有如下几个功能点: 负载均衡服务通过设置虚拟服务地址(IP),将位于同一地域(Region)的多台云服务器(Elastic Compute Service,简称ECS)资源虚拟成一个高性能、高可用的应用服务池;根据应用指定的方式,将来自客户端的网络请求分发到云服务器池中。 负载均衡服务会检查云服务器池中ECS的健康状态,自动隔离异常状态的ECS,从而解决了单台ECS的单点问题,同时提高了应用的整体服务能力。在标准的负载均衡功能之外,负载均衡服务还具备TCP与HTTP抗DDoS攻击的特性,增强了应用服务器的防护能力。 负载均衡服务是ECS面向多机方案的一个配套服务,需要同ECS结合使用。 核心概念 负载均衡服务主要有三个核心概念: LoadBalancer:负载均衡实例。 Listener:用户定制的监听器,定义了负载均衡策略和转发规则。 BackendServer:后端的一组ECS(云服务器)。 下图描述了负载均衡服务的核心概念。来自外部的访问请求,由负载均衡实例根据相关的策略和转发规则分发到后端ECS进行处理。 协议支持 当前提供4层(TCP协议和UDP协议)和7层(HTTP和HTTPS协议)的负载均衡服务。 健康检查 支持对后端ECS进行健康检查,自动屏蔽异常状态的ECS,待该ECS恢复正常后自动解除屏蔽。 会话保持 提供会话保持功能,在Session的生命周期内,可以将同一客户端的请求转发到同一台后端ECS上。 调度算法 支持加权轮询(WRR),加权最小连接数(WLC),和轮询3种调度算法。 加权轮询:根据服务器的处理能力为后端 ECS 分配不同的权值,将外部请求依序分发到后端ECS上,后端ECS权重越高被分发的几率也越大。 加权最小连接数:根据服务器的处理能力为后端 ECS 分配不同的权值,将外部请求分发到当前连接数最小的后端ECS上,后端ECS权重越高被分发的几率也越大。 轮询:将外部请求依序分发到后端ECS上。 域名URL转发 针对七层协议(HTTP协议和HTTPS协议),支持按用户访问的域名和URL来转发流量到不同的虚拟服务器组。 访问控制 支持白名单控制,通过设置负载均衡监听,仅允许特定IP访问,适用于用户的应用只允许特定IP访问的场景。(只能通过Lua) 使用场景 负载均衡主要可以应用于以下场景中: 灵活的进行流量分发,适用于具有高访问量的业务。 横向扩展应用系统的服务能力,适用于各种 web server 和 app server。 消除应用系统的单点故障,当其中一部分 ECS 发生故障后,应用系统仍能正常工作。 提高应用系统容灾能力,多可用区部署,机房发生故障后,仍能正常工作。 https://help.aliyun.com/document_detail/27541.html?spm=5176.doc27543.6.544.5RC2R1 术语表 中文 英文 说明 负载均衡服务 Server Load Balancer 阿里云计算提供的一种网络负载均衡服务,可以结合阿里云提供的 ECS 服务为用户提供基于 ECS 实例的 TCP 与 HTTP 负载均衡服务。 负载均衡实例 Load Balancer 负载均衡实例可以理解为负载均衡服务的一个运行实例,用户要使用负载均衡服务,就必须先创建一个负载均衡实例,LoadBalancerId 是识别用户负载均衡实例的唯一标识。 负载均衡服务监听 Listener 负载均衡服务监听,包括监听端口、负载均衡策略和健康检查配置等,每个监听对应后端的一个应用服务。 后端服务器 Backend Server 接受负载均衡分发请求的一组ECS,负载均衡服务将外部的访问请求按照用户设定的规则转发到这一组后端 ECS上进行处理。 服务地址 Address 系统分配的服务地址,当前为IP地址。用户可以选择该服务地址是否对外公开,来分别创建公网和私网类型的负载均衡服务。 证书 Certificate 用于 HTTPS 协议。用户将证书上传到负载均衡中,在创建 HTTPS 协议监听的时候绑定证书,提供 HTTPS 服务。 主可用区 Master Availability Zone 负载均衡会在某些地域的多个可用区进行部署,用户可指定主备可用区创建负载均衡实例,该实例将默认工作在主可用区。 备可用区 Slave Availability Zone 负载均衡会在某些地域的多个可用区进行部署,用户可指定主备可用区创建负载均衡实例,当主可用区发生故障时,该实例可切换到备可用区工作。

优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:如何避免ANR?

原文地址:http://android.xsoftlab.net/training/articles/perf-anr.html#anr 尽管你写代码可能通过了世界上所有的性能测试,但是它还是可能会让人感觉到卡顿。当应用卡的不成样子时,系统会给你弹一个”Application Not Responding”的对话框。 在Android中,系统会对那些长时间没有响应的应用采取一些措施:弹出一个对话框告诉用户APP已经停止了响应,如下图所示: 正出于这个原因,系统会在APP长时间没有响应的时候为用户提供一个退出APP的选项。所以使APP能够及时响应这一点是至关重要的,这样系统才不会向用户显示ANR对话框。 这节课我们会学习Android系统如何检测应用程序是否是未响应,以及应用程序如何保持响应能力的一些改进措施。 什么触发了ANR? 通常情况下,系统会在应用程序不再能够响应用户的输入时显示ANR对话框。比如,如果应用阻塞在了UI线程的IO操作上,那么系统就不能够处理用户的输入事件。或者应用花费了大量的时间在内存模型的构建上或者是在UI线程中计算了游戏的下一步动作。要记住: 即便是最高效的代码也需要花费时间来运行。 任何情况下都不要在UI线程中执行耗时操作,而是要将这些工作放在一个单独的线程中执行。这可以使UI线程保持流畅工作(UI线程负责驱动用户界面的事件循环)。 在Android中,应用程序的响应态由Activity Manager及Window Manager负责监控。系统会在侦测到以下状况时显示ANR对话框: 对输入事件在5秒内没有作出响应。 BroadcastReceiver在10秒内没有执行完毕。 如何避免ANR? Android应用程序默认运行在UI线程中。这意味着在UI线程中的任何耗时操作都会引发ANR问题,因为这会使应用程序给不到输入事件或者意图广播处理的机会。 因此,在UI线程中的每个方法都应当做尽可能少的工作,尤其是Activity的生命周期回调函数。像网络或数据库操作,或者大量的计算之类的耗时操作应当在工作线程中执行。 创建用于执行耗时操作的线程最便捷的方式莫过于使用AsyncTask了。只需要继承AsyncTask,然后重写doInBackground()就可以执行了。如果要向用户展示工作进度,你可以使用publishProgress()方法,它会回调onProgressUpdate()方法(该方法运行于UI线程)。 在onProgressUpdate()内我们可以更新进度条。 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { // Do the long-running work in here protected Long doInBackground(URL... urls) { int count = urls.length; long totalSize = 0; for (int i = 0; i < count; i++) { totalSize += Downloader.downloadFile(urls[i]); publishProgress((int) ((i / (float) count) * 100)); // Escape early if cancel() is called if (isCancelled()) break; } return totalSize; } // This is called each time you call publishProgress() protected void onProgressUpdate(Integer... progress) { setProgressPercent(progress[0]); } // This is called when doInBackground() is finished protected void onPostExecute(Long result) { showNotification("Downloaded " + result + " bytes"); } } 使用execute()方法启动工作线程: new DownloadFilesTask().execute(url1, url2, url3); 如果不采用这种方式,我们还有另一种实现方法:创建自己的Thread或HandlerThread。如果采用这种方法,那么应该设置该线程的优先级为”background”:通过Process.setThreadPriority()方法及参数THREAD_PRIORITY_BACKGROUND设置。 如果没有设置该优先级,那么该线程会使应用感到变慢,因为该线程的优先级默认与UI线程的优先级一致,它们会互相抢占CPU资源。 如果实现了自己的Thread或HandlerThread,那么要确保在等待其它工作线程完成之前UI线程不被阻塞—不要调用Thread.wait()或Thread.sleep()。如果需要等待其它线程的执行结果,可以为UI线程创建一个Handler。这样做可以使UI线程还可以对 输入事件保持响应能力。这样就可以避免5秒内无响应的ANR对话框出现。 BroadcastReceiver在执行时间上有特殊的限制,这意味着在其内部的工作一定是轻量级的:比如在后台做一些保存设置或者发送通知的工作。所以与UI线程中执行的方法一样,广播接收器内也应当杜绝耗时操作的出现。 TIP: 你可以使用StrictMode来发现UI线程中意外出现的耗时操作。 ANR相关优化 一般来说,100~200毫秒是用户所能感知到应用卡顿的极限。下面列出了一些可以避免应用程序ANR的一些点,同样也有助于防止出现卡顿的情况: 如果应用需要对用户输入做大量的后台工作,可以显示一个进度表示工作正在进行。 对于游戏类的复杂计算,应该将这些工作放在工作线程中执行。 如果应用在初始化阶段需要花费一些时间,可以考虑显示一个闪屏页面或者尽可能快的显示主界面:展示加载正在进行,并进行异步数据填充。在这些情况下都应当表明任务正在进行,以免让用户认为应用已经卡死。 使用Systrace或Traceview等性能工具检查APP的响应瓶颈。

优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:性能优化建议

原文地址:http://android.xsoftlab.net/training/articles/perf-tips.html 本篇文章主要介绍那些可以提升整体性能的微小优化点。它与那些能突然改观性能效果的优化手段并不属于同一类。选择正确的算法与数据结构必然是我们的第一总则,但是这不是我们这篇文章要介绍的。你应该将这篇文章所提及的知识点作为编码的日常习惯,这可以提升常规代码的执行效率。 下面是书写代码的基本准则: 绝不要做你不需要的工作。 如果可以不申请内存就不要申请,要合理复用已有的对象。 另一个较复杂的问题就是被优化过的APP肯定是要运行在各种类型的硬件平台上。不同版本的虚拟机运行在不同的处理器上肯定会有不同的运行速度。需要特别说明的是,在模拟器上测试很少会得知其它设备的性能。在不同设备上还有一个很大的不同点就是有没有JIT(JIT的意思是即时编译器):在JIT设备上运行的最优代码并不总在没有JIT设备上有效。 为了确保APP可以在各类设备上运行良好,要确保代码在各个版本的平台上都是高效的。 避免创建不必要的对象 创建对象绝不是没有成本的。虽然分代垃圾收集器可以使临时对象的分配成本变得很低,但是内存分配的成本总是远高于非内存分配的成本。 随着更多对象的生成,你可能就开始关注垃圾收集器了。虽然Android 2.3中出现的并发收集器可能会帮到你,但是不必要的工作总是应该避免的。 因此,要避免创建不需要的对象。下面的示例可能会帮到你: 如果你有个返回字符串的方法,该方法所返回的字符串总是被接在一个StringBuffer对象后面。那么就可以更改此方法的实现方式:让该字符串直接跟在StringBuffer的后面返回。这样就可以避免创建那些临时性的变量。 当从字符串中提取子串时,应该尝试返回原始数据的子串,而不是创建一个副本。子串将会创建一个新的String对象,但是它与char[]共用的是同一数据。采用这种方式的唯一不足就是:虽然使用了其中的一部分数据,但是剩余的数据还都保留在内存中。 一条更为先进的法则就是,将多维数组转换为平行数组使用: int数组的效率要比Integer数组的效率高的多。 如果你需要实现一个用于存储(Foo,Bar)对象的数组,要记得使用两个平行的Foo[],Bar[]数组,这要比单一的(Foo,Bar)数组效率好太多。 通常来说,要尽量避免创建那些生命周期很短的临时变量。更少的对象创建意味着更低频率的垃圾回收,这会直接反应到用户体验上。 首选静态 如果不需要访问对象的属性,那么就可以将方法设置为静态方法。这样调用将会增加15%-20%的速度。这还是一个好的习惯,因为这样可以告诉其它方法一个信号:它们更改不了对象的状态。 使用常量 请先考虑以下声明: static int intVal = 42; static String strVal = "Hello, world!"; 编译器会产生出一个类的实例化方法,名为< clinit>,它会在类首次被用到的时候执行。该方法会将值42存到intVal中,并将字符串常量表中的引用赋给strVal。当这些值被引用之后,其它属性才可以访问它们。 我们可以使用”final”关键字来改进一下: static final int intVal = 42; static final String strVal = "Hello, world!"; 这样的话,类就不需要再调用< clinit>方法,因为常量的初始化工作被移入了dex文件中。代码可以直接引用intVal为42的值,并且访问strVal也会直接得到字符串”string constant” ,这样可以省去了查找字符串的过程。 Note: 这样优化手段仅仅适用于基本数据类型以及字符串常量,不要作用其它类型。 避免内部的get\set方法 像C++这种本地语言通常都会使用get方法来访问属性。这对C++来说是一个非常好的习惯,并且C#、Java等面向对象语言也广泛使用这种方式,因为编译器通常会进行内联访问,并且如果你需要限制访问或者调试属性的话,只需要添加代码就可以。 不过,这在Android上并不是个好习惯。方法调用的开销是非常大的。虽然为了遵循面向对象语言提供get、set方法是合理的,但是在Android中最好是可以直接访问对象的字段。 在没有JIT的设备中,直接访问对象字段的速度要比通过get方法访问的速度快3倍。在含有JIT的设备中,这个效率会达到7倍之多。 注意:如果你使用了ProGuard,那么就有了一个两全其美的结果,因为ProGuard会直接为你进行内联访问。 使用增强for循环 增强for循环可用于实现了Iterable接口的集合或数组。在集合内部,迭代器需要实现接口方法:hasNext()以及next()。 有以下几种访问数组的方式: static class Foo { int mSplat; } Foo[] mArray = ... public void zero() { int sum = 0; for (int i = 0; i < mArray.length; ++i) { sum += mArray[i].mSplat; } } public void one() { int sum = 0; Foo[] localArray = mArray; int len = localArray.length; for (int i = 0; i < len; ++i) { sum += localArray[i].mSplat; } } public void two() { int sum = 0; for (Foo a : mArray) { sum += a.mSplat; } } zero()方法是最慢的,因为JIT不能够对每次访问数组长度的开销进行优化。 one()方法是稍快点的。它将一切元素放入了本地变量,这样避免了每一次的查询。只有数组的长度提供了明显的性能提升。 two()方法是最快的。它使用了增强for循环。 所以应当在默认情况下使用增强for循环。 Tip: 也可以查看Josh Bloch 的 Effective Java,第46条。 考虑使用包内访问 请先思考以下类定义: public class Foo { private class Inner { void stuff() { Foo.this.doStuff(Foo.this.mValue); } } private int mValue; public void run() { Inner in = new Inner(); mValue = 27; in.stuff(); } private void doStuff(int value) { System.out.println("Value is " + value); } } 上面的代码定义了一个内部类,它可以直接访问外部类的私有成员以及私有方法。这是正确的,这段代码将会打印出我们所期望的”Value is 27”。 这里的问题是:VM会认为Foo$Inner直接访问Foo对象的私有成员是非法的,因为Foo和Foo$Inner是两个不同的类,虽然Java语言允许内部类可以直接访问外部类的私有成员(PS:虚拟机与语言是两种互不干扰的存在)。为了弥补这种差异,编译器专门为此生成了一组方法: /*package*/ static int Foo.access$100(Foo foo) { return foo.mValue; } /*package*/ static void Foo.access$200(Foo foo, int value) { foo.doStuff(value); } 当内部类代码需要访问属性mValue或者调用doStuff()方法时会调用上面这些静态方法。上面的代码归结为你所访问的成员属性都是通过访问器方法访问的。早期我们说通过访问器访问要比直接访问慢很多,所以这是一段特定语言形成的隐性性能开销示例。 避免使用浮点型 一般来说,在Android设备上浮点型要比整型慢大概2倍的速度。 在速度方面,float与double并没有什么区别。在空间方面,double是float的两倍大。所以在桌面级设备上,假设空间不是问题,那么我们应当首选double,而不是float。 还有,在对待整型方面,某些处理器擅长乘法,不擅长除法。在这种情况下,整型的除法与取模运算都是在软件中进行的,如果你正在设计一个哈希表或者做其它大量的数学运算的话,这些东西应该考虑到。 使用本地方法要当心 使用本地代码开发的APP并不一定比Java语言编写的APP高效多少。首先,它会花费在Java-本地代码的转换过程中,并且JIT也不能优化到这些边界。如果你正在申请本地资源,那么对于这些资源的收集能明显的感觉到困难。除此之外,你还需要对每一种CPU架构进行单独编译。你可能甚至还需要为同一个CPU架构编译多个不同的版本:为G1的ARM处理器编译的代码不能运行在Nexus One的ARM处理上,为Nexus One的ARM处理器编译的代码也同样不能运行在G1的ARM处理器上。 本地代码在这种情况下适宜采用:当你有一个已经存在的本地代码库,你希望将它移植到Android上时,不要为了改善Java语言所编写的代码速度而去使用本地代码。 如果你需要使用本地代码,那么应该读一读JNI Tips. Tip: 相关信息也可以查看Josh Bloch 的 Effective Java,第54条。 性能误区 在没有JIT的设备中,通过具体类型的变量调用方法要比抽象接口的调用要高效,这是事实。举个例子,通过HashMap map调用方法要比Map map调用方法要高效的多,开销也少,虽然这两个实现都是HashMap。事实上速度并不会慢2倍这么多;真实的不同大概有6%的减缓。进一步讲,JIT会使两者的差别进一步缩小。 在没有JIT的设备上,通过缓存访问属性要比反复访问属性要快将近20%的速度。在JIT的设备中,属性访问的花销与本地访问的花销基本一致,所以这不是一项有多少价值的优化手段,除非你觉得这样做的话代码更易读(这对static,final,常量同样适用)。 经常估测 在开始优化之前,要确保你有个问题需要解决:要确保你可以精准测量现有的性能,否则将不能观察到优化所带来的提升。 基准点由Caliper的微型基准点框架创建。基准点很难正确获得,所以Caliper将这份很难处理的工作做了,甚至是在你没有在测量那些你想测量的地方的时候它也在工作。我们强烈的推荐你使用Caliper来创建自己的微型基准点。 你可能还发现Traceview非常有助于提升性能,不过你应该意识到Traceview工作的时候JIT并没有开启。这会错误的认为JIT会将损失掉的时间弥补回来。这尤其重要:根据Traceview所更改的结果会使实际代码运行的更快。 有关更多提升APP性能的工具及方法,请参见以下文档: Profiling with Traceview and dmtracedump Analyzing UI Performance with Systrace

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。