`
cherami
  • 浏览: 211423 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Google面试题解说性能之三:不要小看循环中的任何一个语句

    博客分类:
  • Java
阅读更多

对于任何语言来讲,循环永远是非分布式系统的性能的最大杀手,循环中的任何一个简单的语句对性能都是有影响的,只是影响的大小不同而已。第一个例子中的影响是比较大的,不同的实现方法的时间开销不同,然后这个微小的差异被循环次数放大后就非常的明显(3倍),而第二个例子,其本质是减少了循环执行的次数,虽然总的循环次数是一样的,但是最耗时的操作的执行次数被减少到1/10,所以产生的差异是非常巨大的(8倍)。我们再来看一个很不起眼的微小差异带来的影响:
public class GoogleFn {
    private static int MAX = 132000000;

    private static int MAX2 = MAX / 10;

    private static int count(int n) {
        int count = 0;
        while (n > 0) {
            int mod = n % 10;
            if (mod == 1)
                count++;
            n = n / 10;
        }
        return count;
    }

    private static void method1() {
        long start = System.currentTimeMillis();
        int result = 0;
        for (int i = 0; i < MAX2; i++) {
            int number = i * 10;
            int value = count(number);
            for (int j = 0; j < 10; j++) {
                result += value;
                if (j == 1) {
                    result++;
                }
                int x = number + j;
                if (x != 0 && result == x) {
                    print(x, start);
                }
            }
        }
    }

    private static void method2() {
        long start = System.currentTimeMillis();
        int result = 0;
        for (int i = 0; i < MAX2; i++) {
            int number = i * 10;
            int value = count(number);
            for (int j = 0; j < 10; j++) {
                result += value;
                if (j == 1) {
                    result++;
                }
                int x = number + j;
                if (result == x && x != 0) {
                    print(x, start);
                }
            }
        }
    }

    private static void print(int i, long start) {
        System.out.println("Find " + i + ", " + (System.currentTimeMillis() - start) + "ms");
    }

    public static void main(String[] args) {
        method1();
        method2();
    }
}
运行结果:
Find 1, 0ms
Find 199981, 16ms
Find 199982, 16ms
Find 199983, 16ms
Find 199984, 16ms
Find 199985, 16ms
Find 199986, 16ms
Find 199987, 16ms
Find 199988, 16ms
Find 199989, 16ms
Find 199990, 16ms
Find 200000, 16ms
Find 200001, 16ms
Find 1599981, 63ms
Find 1599982, 63ms
Find 1599983, 63ms
Find 1599984, 63ms
Find 1599985, 63ms
Find 1599986, 63ms
Find 1599987, 78ms
Find 1599988, 78ms
Find 1599989, 78ms
Find 1599990, 78ms
Find 2600000, 110ms
Find 2600001, 110ms
Find 13199998, 531ms
Find 35000000, 1453ms
Find 35000001, 1453ms
Find 35199981, 1453ms
Find 35199982, 1453ms
Find 35199983, 1453ms
Find 35199984, 1453ms
Find 35199985, 1453ms
Find 35199986, 1453ms
Find 35199987, 1453ms
Find 35199988, 1453ms
Find 35199989, 1453ms
Find 35199990, 1453ms
Find 35200000, 1453ms
Find 35200001, 1453ms
Find 117463825, 5000ms
Find 1, 0ms
Find 199981, 16ms
Find 199982, 16ms
Find 199983, 16ms
Find 199984, 16ms
Find 199985, 16ms
Find 199986, 16ms
Find 199987, 16ms
Find 199988, 16ms
Find 199989, 16ms
Find 199990, 16ms
Find 200000, 16ms
Find 200001, 16ms
Find 1599981, 63ms
Find 1599982, 63ms
Find 1599983, 63ms
Find 1599984, 63ms
Find 1599985, 63ms
Find 1599986, 63ms
Find 1599987, 78ms
Find 1599988, 78ms
Find 1599989, 78ms
Find 1599990, 78ms
Find 2600000, 109ms
Find 2600001, 109ms
Find 13199998, 516ms
Find 35000000, 1438ms
Find 35000001, 1438ms
Find 35199981, 1438ms
Find 35199982, 1438ms
Find 35199983, 1438ms
Find 35199984, 1438ms
Find 35199985, 1438ms
Find 35199986, 1438ms
Find 35199987, 1438ms
Find 35199988, 1438ms
Find 35199989, 1438ms
Find 35199990, 1438ms
Find 35200000, 1438ms
Find 35200001, 1438ms
Find 117463825, 4938ms

注意我们的MAX值比以前的例子放大了10倍,因为这个例子的差异比较小,值太小看不出差异,注意到两个方法的不同了吗?对,仅仅是if里面的条件换了个位置:
x != 0 && result == x  -》 result == x && x != 0
你还可以稍稍修改下代码,把后面的那个的&& x != 0去掉,你会发现它的结果和这个结果很类似。
这个原理就是&&运算符的短路原理,如果前面的条件不为true,那么后面的计算不被执行。
所以循环中的任何代码都要比较小心,即使一点细小的不同都会在循环的放大作用下产生一些不好的结果。

PS: 条件判断中有多个并列条件时,前面放的应该是最少满足的条件,这样可以更好的过滤。

分享到:
评论
3 楼 wtb 2007-05-22  
支持楼主,
架构固然重要,但代码质量也同样重要。楼主所列举的这些性能的问题其实所有人都知道,但很多人都没有注意和下功夫,最终整个产品质量不高。我见过很多这样的例子,刚写出来的一个不大的程序执行要花大量时间,用jprofile监控加调试,一个语句一个语句的优化。最终性能很棒。试想,如果平时就养成习惯多注意这些“细小”的性能问题,那么在动手做个大的系统时就不怕了。
2 楼 cherami 2007-04-29  
如果那个操作要执行上百亿次呢?就像计算这个fn一样?
1 楼 justcode 2007-04-29  
个人认为不要在这些小的地方磨蹭,而应在架构和扩展性上做文章.

String 的"+"和StringBuffer的"append"也就多耗个100ms而已,而且还要看是多大的字符串.

相关推荐

    前端面试题:前端框架面试题大全

    前端面试题:前端框架面试题大全; 前端面试题:前端框架面试题大全; 前端面试题:前端框架面试题大全; 前端面试题:前端框架面试题大全; 前端面试题:前端框架面试题大全; 前端面试题:前端框架面试题大全; ...

    jmeter性能面试问答题

    JMeter是一款强大的性能测试工具,常用于模拟大量用户并发访问Web应用程序,以评估系统的性能和稳定性。以下将详细介绍JMeter的使用、线程组配置及性能测试的关键点。 **JMeter录制与过滤** JMeter可以通过BadBoy等...

    常见的性能测试工程师面试题(附答案)

    性能测试工程师面试题是指性能测试工程师在面试过程中遇到的常见问题,涵盖了性能测试的基础知识、LoadRunner 的使用、场景设置、脚本录制、参数设置、关联机制、调试技巧等多个方面。 1. 负载测试和性能测试的区别...

    GOOGLE面试题集锦

    在 IT 行业中,面试是企业选拔人才的重要步骤之一,而 Google 作为全球顶尖的科技公司,其面试方式也备受关注。Google 面试题集锦就是一个集合了 Google 面试题的资源,涵盖了逻辑、数学、算法等多个方面的知识点。 ...

    性能测试面试题宝典-覆盖大部分性能专项面试题

    性能测试面试题宝典--覆盖大部分性能专项面试题性能测试面试题宝典--覆盖大部分性能专项面试题性能测试面试题宝典--覆盖大部分性能专项面试题性能测试面试题宝典--覆盖大部分性能专项面试题性能测试面试题宝典--覆盖...

    sql面试题很详细的sql语句面试题

    本资源旨在总结和详细解释SQL面试题中的各种问题和解决方案,并对每个问题进行了详细的解释和分析。 一、查询每门课都大于80分的学生姓名 问题:使用一条SQL语句查询出每门课都大于80分的学生姓名。 解决方案:...

    10万字总结java面试题和答案(八股文之一)Java面试题指南

    Java中的IO与NIO面试题 Java反射面试题 Java序列化面试题 Java注解面试题 多线程&并发面试题 JVM面试题 Mysql面试题 Redis面试题 Memcached面试题 MongoDB面试题 Spring面试题 Spring Boot面试题 Spring Cloud面试题...

    牛客大数据面试题集锦+答案,共523道,46W+字。大厂必备

    以后会慢慢把Java相关的面试题、计算机网络等都加进来,其实这不仅仅是一份面试题,更是一份面试参考,让你熟悉面试题各种提问情况,当然,项目部分,就只能看自己了,毕竟每个人简历、实习、项目等都不一样。面试题...

    2021最新Java面试题合集.zip

    - **Netty** 是一个高性能、异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。 2. **Java并发编程最全面试题 123道**: - **线程安全**:Java中的`synchronized`关键字、`volatile`...

    经典sql语句(SQL经典面试题及答案,某外企SQL Server面试题L)

    本资源“经典sql语句”聚焦于SQL的经典面试题及其解答,旨在帮助求职者特别是针对SQL Server岗位的应聘者准备面试。以下将详细解析SQL的一些核心知识点,并结合可能的面试问题进行阐述。 1. **选择查询(SELECT)**...

    一份就够!史上最全面Python面试题和详解(10个文件)看完啥都会了.zip

    文档“python面试题搜集(六):110道Python面试题(上).md”和“python面试题搜集(六):史上最全python面试题详解(三).md”可能包含更多实战性问题,涉及Python性能优化、并发编程、设计模式以及Python与其他...

    sql语句的内联外联 经典面试题

    在面试中,SQL语句的内联外联经典面试题是一个非常重要的考察点。本文将对SQL语句的内联外联进行详细的介绍和分析,并提供了一些经典的面试题和答案,以便读者更好地理解和掌握SQL语句的内联外联。 一、SQL语句的...

    C语言面试题大汇总之华为面试题:1、局部变量能否和全局变量重名;2、如何引用一个已经定义过的全局变量;3、全局变量可不可以定义在可被多个.C文件包含的头文件中 为什么;4、语句for( ;1 ;)有什么问题 它是什么意思……

    本文总结了C语言面试题大汇总之华为面试题,涵盖了局部变量、全局变量、extern关键字、for循环、while循环、静态变量、静态函数、内存分配等知识点。 一、局部变量和全局变量 局部变量可以与全局变量同名,在函数...

    2021-最新大厂AI面试题q2版121题:含答案及解析21.7.23

    在面试中,掌握这些知识点可以帮助自己更好地应对面试官的问题,提高自己的面试成功率。 此外,这些知识点也可以作为学习和复习的 reference,帮助同学们更好地学习和掌握人工智能领域的知识。 这些知识点涵盖了...

    08-谷歌面试题-08-谷歌面试题

    在面试题中,我们可以看到数据分析的应用,例如找到每个国家第三高的山峰。数据分析是指对数据进行处理、转换、分析和解释,以便获取有价值的信息和结论。 * 数据分析步骤:问题定义、数据收集、数据清洁、数据分析...

    java 面试题基础题,sql 面试题 带答案

    Java 和 SQL 是 IT 行业中两个至关重要的技术领域,特别是在软件开发和数据库管理中。以下是对这些领域的基础面试题及答案的详细解读。 一、Java 面试题 1. **Java 的特点:** Java 以其跨平台性、安全性、高性能...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    面试题包含了不同技术层面的面试问题,同时也能对一些没有面试开发经验的小白给予不可估量的包装, 让你的薪水绝对翻倍, 本人亲试有效.Java面试题84集、java面试专属及面试必问课程,所有的面试题有视屏讲解, 解答方案....

    java私塾面试题----SQL语句2

    6. **子查询**:子查询是在一个SQL语句中嵌套另一个SQL查询,用于获取满足特定条件的子集数据,可以作为其他查询的一部分。 7. **视图(VIEW)**:视图是虚拟表,基于一个或多个表的查询结果,提供了一种简化数据...

    java面试题(SQL语句).pdf

    在Java面试中,掌握SQL语句是至关重要的,因为大多数应用程序都需要与数据库进行交互。SQL,全称为结构化查询语言,是用于管理关系数据库的标准语言。以下是对SQL语句的详细解析,主要涵盖DDL(数据定义语言)、DML...

Global site tag (gtag.js) - Google Analytics