• 2008-08-11

    《秒杀十分钟》再之后

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-logs/27554947.html

    经过周末的休息,重新回到工作之中,而我面对的依然是那个需要优化的发布过程。正如我在之前提到过的,在上周末结束工作之前,我为这周的工作留下了一个尾巴:需要算分的企业。

    回顾一下我在之前列出的公式:
        需要算分的企业 * (真正算分的时间 + 保存历史的时间)

    从这个公式中,我们可以清晰的看到,需要算分企业的多少将直接决定循环次数的多少。但需要算分的企业真的能减少,会不会破坏业务逻辑,我们还不是特别清楚。所以,我们先要与我们可爱的BA(业务分析师)进行讨论,因为他们是项目组里面最了解业务的人。目前的逻辑是,只要有新的发布,那就会把与发布相关品牌的所有企业拿出来算分,按照我们的分析,其实没有这个必要,因为这次发布的内容可能并不会影响到有些企业。经过与BA的讨论,BA认同了我们的观点,接下来,要做的就是用实际数据测试一下,如果真的这么做了,会不会有改变。测试的数据,比较让人兴奋,我们随机的做了一次发布,涉及到的企业数就下降到原来的一半,这意味着,运行时间接近缩减到原来的一半。虽然我们需要增加一些逻辑判断企业是否需要算分,但对比于能够削减的时间而言,简直就是微不足道。那个让我们吃了午饭还有空闲的程序,已经大幅度的缩减了,至少现在我们已经敢把所有的程序都跑完了。

    继续分析日志,我们又找到一些算分时间特别长的企业,之所以这些企业之前没有发现,主要还是归功于运行时间太长,我们没有勇气运行完所有的程序,或者说,不想偷懒到那种地步。把一个企业单独拿出来算分,运行时间在25秒中以上,其中保存历史大约10秒种,也就是纯粹算分时间在15秒左右。这可是经过之前的优化,否则时间会更长。

    我们打开代码继续分析,我和Pair突然发现了一个问题,还是与分类相关。之前提到过,我们一次计算需要算6类的分数,但是,对于我们计算的目标而言,它只可能属于一个分类,所以,其它5类的结果必然没有任何意义。之所以之前计算了所有类别,主要是考虑到它可能会涉及到多个类别,但目前的需求已经统一到一个类别,也就是需求已经变了,但代码没有变,虽然代码很成功的覆盖了目前的情况,但也为之付出了代价。理解了这一点,我们又一次修改了代码,真正算分的操作降到了10秒左右。

    从需要算分的企业优化尝到甜头的我们,看到削减大规模计算次数的好处。所以,我们继续试图从目前的代码中发现一些可以削减计算的目标。果不其然,我们还是有机会的。

    我们每次发布其实可能只有几个需要算分的目标,但这里的计算却把这个企业所涉及的所有目标全部拿出来算分,这显然是一个非常浪费时间的操作。我们用来测试的企业,之所以被我们找了出来,原因就是它有113个需要算分的目标,而事实上,我们的发布只有1个。不过,之前一直没有保留其它算分目标的计算结果,因为,每次都重新计算,所以,倒也不必保留。不过,现在要想提高性能,我们就不得不采用空间换时间的策略,把计算过的结果保存下来,只有这次发布涉及到的目标才重新计算。我们的选择是在数据库表中增加一个字段保存计算结果,不过,考虑到之前一直没有采用这种方法,我们就在程序中加以处理,当这个字段为空的时候,就重新计算这个字段的结果。第一次跑这个程序的时候,我们并没有明显感觉到程序运行加快,因为数据库表中这个字段都是空,所有的数据都需要重新计算,但第二次计算时,速度明显加快了需要,1秒以内就可以完成。当然这个数字取决于一次发布包含的目标个数,显然,比起10秒好了很多。

    我们用这段代码对产品数据进行测试,第一次依然是一个漫长的过程,不过,第二次发布明显快了很多,大约在20分钟左右,所有的操作就宣告完成,对,就是那个曾经耗时几个小时的过程。

    我想,这次优化至此就要告一段落了。现在的这段程序优化到已经可以接受的程度了,在最开始的那个公式中,除了保存历史部分,其他部分都已经做了足够的优化。当然,我相信,保存历史部分也可以优化,但目前来说,就到这里了。

    有人在《<秒杀十分钟>之后》之后留言:
    玩企业应用的,只要精通数据库和SQL就足够了。

    我并不是太同意这个说法,从我写的这三篇blog中,可以看出,其实,真正属于SQL优化的少之又少,大部分都是逻辑的分析上。所以,如果有时间抱怨程序设计语言慢(比如Ruby),不妨先考虑一下自己的程序逻辑是不是真的写对了。

    做了三天性能优化的工作,这是最近一段时间玩得最High的几天。眼瞅着程序几倍、几十倍的提升着,心里非常痛快,当然,第一天成百上千倍的提升是最快乐的。

    这就是程序设计的快乐之处!

    分享到:

    历史上的今天:

    虚假的泛型 2005-08-11
    引用地址:

    评论

  • 很奇怪,看完通篇,发现有可以优化的地方原来是本来程序写的不合理。没真正理解需求?冗余代码?性能问题是怎么发生的?没有把来龙去脉说清楚。
    回复字符串说:
    有很多所谓的优化,改变的其实是算法。不能说之前是不理解需求,因为之前的代码是满足需求的。而通常没有出线性能问题之前,这些算法的不足是不会体现出来的。只有出了问题,我们才会思考每一个细微的点。
    2008-11-02 15:05:16
  • 幸福的是,玩了优化,还能纪录下来,share到blog上,更幸福的是,还有看客留言,授人以渔。
  • 能有机会玩优化,兄弟真是幸福啊!!