Android 应用性能优化(三) 多核下的多线程计算

多核的处理器不同于单核处理器,可以同时执行多个线程。可以说,在理论上双核的处理器的性能是单核的两倍,基本上我们一般不用操心这个设备到底是多核还是单核的,因为使用Thread或者AsyTask将工作分派给不同线程就足够了。如果处理器是多核的,那这些线程就会运行在不同的核心上,但是可能有的时候要最有效的使用CPU来获得可接受的性能,要特别为多核定制算法。

以下实现做的事情:

1.将原问题划分成多个更简单的子问题

2.然后将子问题的结果合并处理,算出原问题的解(使用Future和ExcecutorService)

3.成功避免了重复计算很多相同的斐波那契数(使用高并发高吞吐并且线程安全的ConcurrentHashMap作为缓存)

代码如下:

private static final int proc = Runtime.getRuntime().availableProcessors();  
   private static final ExecutorService executorService = Executors.newFixedThreadPool(proc + 2);  
  
   public static BigInteger recursiveFasterBigInteger(int n ){  
       if(n>1) {  
           int m = (n/2) + (n&1);  
           BigInteger fM = recursiveFasterBigInteger(m);  
           BigInteger fM_1 = recursiveFasterBigInteger(m-1);  
           //合并结果,计算出原问题的解  
           if((n&1)==1){  
               return fM.pow(2).add(fM_1.pow(2));  
           }else {  
               return fM_1.shiftLeft(1).add(fM).multiply(fM);  
           }  
       }  
       return (n==0)?BigInteger.ZERO:BigInteger.ONE;  
   }  
  
   private static BigInteger recursiveFasterWithCache(int n) {  
       HashMap<Integer, BigInteger> cache = new HashMap<Integer, BigInteger>();  
       return recursiveFasterWithCache(n, cache);  
   }  
  
   private static BigInteger recursiveFasterWithCache(int n, Map<Integer, BigInteger> cache) {  
       if (n > 92) {  
           BigInteger fN = cache.get(n);  
           if (fN == null) {  
               int m = (n / 2) + (n & 1);  
               BigInteger fM = recursiveFasterWithCache(m, cache);  
               BigInteger fM_1 = recursiveFasterWithCache(m - 1, cache);  
               if ((n & 1) == 1) {  
                   fN = fM.pow(2).add(fM_1.pow(2));  
               } else {  
                   fN = fM_1.shiftLeft(1).add(fM).multiply(fM);  
               }  
               cache.put(n, fN);  
           }  
           return fN;  
       }  
       return BigInteger.valueOf(iterativeFaster(n));  
   }  
  
   public static BigInteger recursiveFasterWithCacheAndThread(int n) {  
       int proc = Runtime.getRuntime().availableProcessors();  
       if (n < 128 || proc <= 1) {  
           return recursiveFasterWithCache(n);  
       }  
  
       final ConcurrentHashMap<Integer, BigInteger> cache = new ConcurrentHashMap<Integer, BigInteger>();  
  
       final int m = (n / 2) + (n & 1);  
  
       Callable<BigInteger> callable = new Callable<BigInteger>() {  
           @Override  
           public BigInteger call() throws Exception {  
               return recursiveFasterWithCache(m,cache);  
           }  
       };  
  
       Future<BigInteger> ffM = executorService.submit(callable);  
  
       callable = new Callable<BigInteger>() {  
           @Override  
           public BigInteger call() throws Exception {  
               return recursiveFasterWithCache(m-1,cache);  
           }  
       };  
       Future<BigInteger> ffM_1 = executorService.submit(callable);  
  
       //得到各部分的结果开始合并  
       BigInteger fM,fM_1,fN;  
  
       try{  
           fM = ffM.get();//获取第一个子问题的结果(阻塞调用)  
       }catch (Exception e){  
           //如果抛出了异常 那就在当前主线程中计算fM  
           fM = recursiveFasterBigInteger(m);  
       }  
  
       try{  
           fM_1 = ffM_1.get();//获取第一个子问题的结果(阻塞调用)  
       }catch (Exception e){  
           //如果抛出了异常 那就在当前主线程中计算fM  
           fM = recursiveFasterBigInteger(m-1);  
       }  
  
       if((n & 1) != 0 ){  
           fN = fM.pow(2).add(fM_1.pow(2));  
       }else {  
           fN = fM_1.shiftLeft(1).add(fM).multiply(fM);  
       }  
       return fN;  
   }

其实很多时候即使把问题分解为子问题并将子问题分派到不同的线程,性能也有可能并没有什么提升,有可能是数据之间有依赖,不得不进行同步,线程就可能会花大部分的时间在等待数据。所以实践中通常是用多线程执行无关的任务,避免同步需求。

时间: 2024-10-24 11:11:01

Android 应用性能优化(三) 多核下的多线程计算的相关文章

《Android应用性能优化》 第5章 多线程和同步

1.DDMS中可以看见的系统线程(Andorid3.1的Galaxy Tab 10.1为例): main HeapWorker 执行finalize函数和引用对象清理 GC Garbage Collector垃圾收集 Signal Catcher 捕捉Linux信号进行处理 JDWP Java Debug Wire Protocol 调试协议服务 Compiler JIT compiler 即时编译器 Binder Thread #1 Binder通讯 Binder Thread #2 2.Th

Android 性能优化 三 布局优化ViewStub标签的使用

小黑与小白的故事,通过虚拟这两个人物进行一问一答的形式来共同学习ViewStub的使用 小白:Hi,小黑,ViewStub是什么?听说可以用来进行布局优化. 小黑:ViewStub 是一个隐藏的,不占用内存空间的视图对象,它可以在运行时延迟加载布局资源文件.(更多详细的API等信息可以查看官方文档ViewStub),计算机行业一向是实践里面出真知,下面用一个例子演示下效果. 小黑:说说概念只是为了概括性的了解下,还是用个实例来演示下.先来创建一个Activity中使用的布局文件,文件名是:act

Android开发性能优化总结(一)

安卓开发应用首先要讲究良好的用户体验,如果一款软件卡顿现象严重,不流畅,经常崩溃,那么将给用户带来极不良好的体验,从而损失用户. 在实际开发和学习中,我总结了一下关于安卓性能的优化,供大家参考交流. 应用程序的性能问题体现在很多方面, 比如第一次启动速度慢,或者进入某一界面速度慢:动画执行过程不流畅,或者动画执行卡顿时间长:ListView列表滑动过程中卡顿,不流畅:应用程序自定义的某特定界面执行速度慢:响应某一用户事件时长时间无响应(ANR):操作数据库时,执行大量数据的增删改查操作,执行速度

Android客户端性能优化(魅族资深工程师毫无保留奉献)

本文由魅族科技有限公司资深Android开发工程师degao(嵌入式企鹅圈原创团队成员)撰写,是degao在嵌入式企鹅圈发表的第一篇原创文章,毫无保留地总结分享其在领导魅族多个项目开发中的Android客户端性能优化经验,极具实践价值! 即日起,嵌入式企鹅圈将在之前五个专栏(Linux内核驱动情景分析.资源紧缺型SOC嵌入式架构设计.嵌入式交叉工具链及其应用.嵌入式设计和编程.微信硬件平台和物联网解决方案)新增Android开发专栏!更多Android.Linux.嵌入式和物联网原创技术分享敬请

Android开发性能优化总结(二)

接上一篇<Android开发性能优化总结(一)> 一.安卓UI性能检测与优化 UI是安卓应用程序与用户打交道的最直接途径,UI设计的好不好,直接影响到用户的体验,如果没有达到他们心目中的自然流畅细节,用户要是能够感觉出来,少则影响心情,多则卸载应用:所以一个应用的UI显示性能问题就不得不被开发人员重视. 1.UI卡顿常见原因: 在UI线程中做了耗时操作,导致UI线程卡顿: 布局Layout过于复杂,无法在16ms内完成渲染: 同一时间动画执行的次数过多,导致CPU或GPU负载过重: View过

Android APP 性能优化的一些思考

说到 Android 系统手机,大部分人的印象是用了一段时间就变得有点卡顿,有些程序在运行期间莫名其妙的出现崩溃,打开系统文件夹一看,发现多了很多文件,然后用手机管家 APP 不断地进行清理优化 ,才感觉运行速度稍微提高了点,就算手机在各种性能跑分软件面前分数遥遥领先,还是感觉无论有多大的内存空间都远远不够用.相信每个使用 Android 系统的用户都有过以上类似经历,确实,Android 系统在流畅性方面不如 IOS 系统,为何呢,明明在看手机硬件配置上时,Android 设备都不会输于 IO

Android app 性能优化的思考--性能卡顿不好的原因在哪?

说到 Android 系统手机,大部分人的印象是用了一段时间就变得有点卡顿,有些程序在运行期间莫名其妙的出现崩溃,打开系统文件夹一看,发现多了很多文件,然后用手机管家 APP 不断地进行清理优化 ,才感觉运行速度稍微提高了点,就算手机在各种性能跑分软件面前分数遥遥领先,还是感觉无论有多大的内存空间都远远不够用.相信每个使用 Android 系统的用户都有过以上类似经历,确实,Android 系统在流畅性方面不如 IOS 系统,为何呢,明明在看手机硬件配置上时,Android 设备都不会输于 IO

【读书笔记】《Android应用性能优化最佳实践》

<第一行代码>读书笔记 一.引言 二.读书内容 书名:<Android应用性能优化最佳实践> 作者:罗彧成 (腾讯音乐Android开发总监) 出版社:机械工业出版社 封面: 三.书籍评价 四.个人心得 五.参考文档

Android内存性能优化(内部资料总结)

刚入门的童鞋肯能都会有一个疑问,Java不是有虚拟机了么,内存会自动化管理,我们就不必要手动的释放资源了,反正系统会给我们完成.其实Java中没有指针的概念,但是指针的使用方式依然存在,一味的依赖系统的gc,很容易就造成了内存的浪费.   Java基于垃圾回收的内存机制 Java的内存管理机制会自动回收无用对象所占用的内存,减轻手工管理内存的负担 1.C/C++: 从申请.使用.释放都需要手工管理 2.Java:无用的对象的内存会被自动回收 什么样的对象是无用的对象 1.Java通过引用来操作一