Menu

程序员编程生产力相差10倍意味着什么,无法衡量的软件开发生产效率

2003年8月29日,软件行业大牛Martin
Fowler写过《无法衡量生产效率》。10年后,Martin
在其网站首页以《十年后仍无法衡量生产效率》标题再次推荐了这篇文章,并附言:
引用软件行业的巨大挫败之一,是我们没有合理建立研究,去思考诸如面向对象编程和测试驱动开发之类的开发工具和技术、还有其他更高级的语言是否对我们有益。我们经常看到不当的研究,并且常常很糟糕,是因为它们是基于一个错误的衡量方法。十年前的今天,我的挫败感促使我写了《无法衡量生产效率》一文。我认为该文在今天看起来,和十年前没什么不同。原文内容如下:我们见到过太多关于软件开发过程、设计实践以及类似内容充满激情的讨论。它们当中有很多是无法验证的,因为软件行业没有能去衡量代表开发效率的一些基本元素。特别是我们无法合理地衡量生产效率。当然,生产效率可以通过观察生产过程的输入与产出来衡量。所以,要衡量软件开发的生产效率,你就必须去衡量软件开发的产出。我们无法衡量生产效率的根源就在于我们无法衡量产出。并不是说人们没有尝试过。最令我气愤的就是那些用代码行数来衡量生产效率的研究。首先,总是存在不同的语言、不同的计数方式、不同的格式化风格造成的问题。即使采用一致的计数标准,衡量相同语言代码,且代码被自动格式化为统一的风格,代码行数仍然无法正确反映产出。任何优秀的开发者都知道,让他们去实现一个特定功能所需的代码行数可能相差巨大。除此之外,精心设计以及重构过的代码都会更短小,因为它消除了冗余。复制粘贴风格的程序会有更多的行数以及更差的设计,因为它充满冗余。这很好证明,只要你使用一个支持inline
method的重构工具去修改一个程序。只需用这个工具去重构那些普通函数,你就可以轻易让代码行数翻倍。你可能觉得已经没人再用代码行数了,实际上每个月我都能看到基于代码行数的生产效率研究论文,甚至是在类似IEEE
Software这样令人尊敬的期刊上。也不是说代码行数是个完全没用的衡量,它能很好代表系统规模。我可以很确定一个100
KLOC的系统比一个10KLOC的系统要大。但是如果我用了一年时间写了那个100KLOC的系统,而Joe在一年内用10KLOC实现了同样的系统,这无法说明我更高产。实际上我得到的结论是:我们的生产效率差不多,但我的系统设计得更差。另一个经常被用来衡量产出的方法是使用功能点。虽然我更同情这种做法,但它并不能令我信服。我听过很多这样的故事:同一个系统,不同人统计的功能点数目相差有3倍之多。即使我们能够找到一种方式用功能点精确衡量功能,我认为这仍然无助于解决生产效率的衡量问题。可以这么说,衡量功能点是观察软件开发直接产出的方式,但真实产出确是另一回事。假设有一个精确的功能点计算系统,如果我花一年发布了一个有100个FP的系统,同时Joe也用一年发布了一个50FP的系统,是不是就能说我更高产?我觉得不是。很可能我做的100FP中只有30个对我的客户来说是真正有用的功能,而Joe开发的功能则全部都是有用的。我会这么说:虽然我的直接生产效率更高,但Joe的真实生产效率更高。Jeff
Grigg向我指出,还存在影响功能点交付的内因。我的100个功能点可能提供的都是很相似的功能,我之所以花了一年时间,是因为我没有很好的重用代码。Joe的50个功能都是差别相当大的,所以几乎没有重用的可能。尽管需要实现50个相当不同的功能,并且几乎无法重用代码,但Joe真的很棒,他在一年之内就全部完成了。但这些都忽视了一点:即使是有用的功能也无法真正用来做衡量。假设我有了进步,完成了30个有用的功能点,同时Joe只完成了15个。但有人会发现Joe的15个功能点为我们的客户增加了1千万的盈利,但我的工作成果带来的盈利只有500万。我仍然认为Joe的真实生产效率要比我高,因为他产出了更多的商业价值。并且我坚信任何真正的软件生产效率衡量必须基于其所带来的商业价值。这种思想也适用于成功率。通常关于软件项目成功的判断都是虚假的,因为人们并不理解什么是失败。我可以说一个成功的项目就是产生的商业价值大于研发成本的项目。假如Joe和我各参与了5个项目,我的4个项目是成功的,而Joe只有一个项目成功。这是不是就意味着我干的比Joe好呢?这可不一定。如果我的4个项目每个盈利1百万,而Joe那个成功项目的收入比他所有的5个项目成本的总和还要多出1千万,那么他才是那个应当获得提拔的人。有些人会说“如果无法衡量,就无法管理”,这是站不住脚的。商业领域中,人们一直在管理着那些他们无法衡量价值的东西。你如何衡量一个公司里律师的生产效率?如何衡量市场部门、教育机构?你无法衡量,但你任然需要去管理它们。如果团队的生产效率都很难衡量,那么个人对团队的贡献就更难衡量了。通过观察每个迭代产出特性的多少,你可以对团队的产出有个大致的概念。这是个很粗糙的感受,但是你可以感觉出团队的速率是否有所提高,或者大致感觉出两个团队的生产效率哪个更高一些。但是个人的贡献值就很难计算了。可能有的成员职责是实现特性,而有些成员的角色可能是协助者——他们负责帮助他人实现特性。他们的作用是提升整个团队的生产效率——除非你是这个团队中的一个开发者,你将很难搞清楚这些人的产出到底是什么。如果你觉得这些情况还不够复杂,在《经济学人》上有一篇关于生产效率趋势的文章。经济学家们似乎发现,由于90年代中对计算机产业的投资导致了如今商业领域中生产效率的提升。这其中的重点是——增长是落后于投资的:“对计算机方面的投资并不会自动地推动生产效率提升,公司同时也需要重组他们的商业实践”。同样的滞后效应也出现在电力发明之后。所以商业价值不仅难于衡量,还存在时延。很可能直到团队构建的软件发布多年之后,你才能够衡量团队的生产效率。我可以理解为什么衡量生产效率如此具有诱惑性。如果可以做到,我们就可以更容易、更客观地评估软件。然而错误的衡量方式只会使问题恶化。我觉得必须承认:在这一领域,我们任然很无知。英文原文:Martin
Fowler / 译文:伯乐在线

  软件开发中个人效率的变化

  本文摘自《软件之道:软件开发争议问题剖析》

  到底有没有办法可以测量个人生产力

  软件设计是一件非确定性的事情,对同样的一个问题,不同的设计师/开发人员会做出完全不同的解决方案。如果我们用每月产出的代码行数(或者类似的标
准)来衡量生产力,那么我们就默认了用10倍的代码来解决同样的问题的程序员就有10倍的生产力。显然事情并非总是如此。比如某个程序员可能会有一个绝妙的设计想法,结果只用10%的代码就解决了普通程序员需要100%的代码才能解决的问题。

  管理者常说:“我总是把最困难、最复杂的编程任务交给最好的程序员去做。所以无论用什么方法来衡量,他的生产力好像总是比别人低,但是如果同样的事情让别人来做,就可能花上两倍的时间。”这种现象很正常,但是也会影响我们定义和测量生产力的方式。

  如前所述,这个例子说明了造成生产力差距的各种因素。Lotus和微软都煞费苦心地为各自的项目招募了顶级的人才,所以我怀疑团队生产力的差距并不只是由于团队成员的能力差距造成的,还牵扯到了很多组织结构上的因素,比如产品远景是否清楚、客户需求是否明确以及成员之间是否能同心协力,等等。

  通常来说,任何对10倍程序员的实用定义都必须考虑这样的程序员对于团队其他人员的影响。我也知道的确有牛哄哄的超级程序员。但更多的时候,那些牛哄哄的超级程序员其实只是普通水平的一般程序员而已,甚至还达不到普通水平。他们只是用牛哄哄的外表来让自己的表现看上去不那么差而已。我所共事过的真正的超级程序员们除了技术水平以外,通常还有很好的团队精神(虽然有时也有些例外)。

  那次研究之后,还有很多其他关于专业程序员的相关研究都证明了一个结论:程序员的水平也分三六九等。

  测量程序员的个人生产力的问题

  有趣的是,这些量化的结果和局外人对于这些项目的感觉非常贴近。Lotus
1~2!3第三版当时是出了名的跳票王,比预期的时间至少晚了两年才发布。而在微软内部,Excel大受赞扬,被誉为是微软最成功的项目之一。对于真实公司的
真实项目,这种程度的同类比较恐怕已经是能做到的极致了。

  在软件行业中似乎就是这样。在多个已发表的关于软件开发效率的研究项目中,大约有10%的实验参与者无法完成实验任务。这些研究报告常常会这样说
道:“所以我们从数据集中排除了这些参与者的结果。”但是在现实生活中,如果某个人“无法完成任务”,你就不能简单地“从数据集中排除他们的结果”了。你或者得等他们完成,或者得另外指派一个人完成他们的工作,等等。这里有一个有趣(而又可怕)的暗示,那就是在软件行业中,差不多有10%的人对项目产出的贡献是负数。

  Augustine的研究发现,由于有些人完全没有任何实质的贡献(例如不能得分的前锋、没有专利的发明家、无法破案的警探等),人与人之间的差距的实际情况可能比上文提到的数据还要大。

  在详细地研究了Sackman、Erickson以及Grant的研究结果之后,我们可以发现他们所使用的方法中有很多缺陷,例如把使用低级程序语言和高级程序语言的程序员合在一起研究等。但是,即便把这些缺陷考虑进来,他们的数据也仍然表明,最好的程序员和最差的程序员之间的差距能达到10倍以上。

  又比如,在一次对7个完全相同的项目的研究中,研究人员发现,在这些团队中耗费精力最多的是最低的3.4倍,而对于程序的大小,最大的是最小的3倍
。虽然生产力有一定差距,但是这次研究中的程序员都来自相似的背景。他们都是科班出身的职业程序员,而且都有多年的经验。我们可以合理地推测,如果研究对象的背景差异再大一些,那么他们之间的差距会更大。早期的一份对编程团队的研究曾指出,对于同样的项目,不同团队所提交的程序大小的比例可以达到
5∶1,而所需时间的比例可以达到2.6∶1。

  和此前一样,这也和我们在现实生活中的感受一致。我相信很多人都能够在共事过的人中找出符合这个描述的人。

  Barry Boehm等研究人员为了确立COCOMO
II成本估算模型而研究了超过20年的数据,并总结到:对于同样的程序,能力评分在15+的团队需要的时间是得分为90+的团队的3.5倍(以100分算)。
如果一个团队比另一个团队在程序语言或者应用领域上更有经验,那么这个差距还会更大。

  美高梅开户,软件开发中的团队生产力差距

  Dilbert漫画中有一个故事:老板说每发现一个bug就奖励10块钱,大家都高呼这次赚到了,还有人想通过这个办法“写出辆小货车”来
。故事正好说明了这个问题,即如果你用代码的产出量来衡量生产力,有的人就会利用这一点,写很多很多也许完全没有必要的代码。这里的问题并不在于“代码量”这个标准,而在于旧式的管理思想,即“人们只会做会被考察的事情”。但你必须小心不要考察错东西。

  什么造就了真正的“10倍程序员”

  前文提到的这些困难让很多人认为:要想测量个人生产力简直困难重重,没人可以做到。但我认为要想正确地测量个人生产力是可能的,只是需要注意以下几点。

  很多人并不喜欢被贴上“10倍”这样的标签,因为他们觉得人们会说:“我们团队中曾有个超级程序员,他牛哄哄的,每个人都不愿和他来往,要是没有他整体效率反而还要高些。”

  复杂度呢

  • 不要指望仅用一个单独的衡量标准就能了解个人生产力的实际整体状况

    你可以参照一下那些在体育比赛中搜集的统计数据。我们甚至无法用一个单独的标准来确定棒球比赛中击球手的水平。我们必须考虑打击率、全垒打、跑垒得分、上
    垒率以及其他种种因素。而且仅有这些数据还不够,我们还得去证明这些数据的意义。如果击球手的优劣无法用简单的标准来评断的话,难道程序员的个人生产力这样复杂的事情就可以吗?我们应该用的不是一个单独的标准,而是一整套标准的组合。这套组合标准的任务,就是让我们对个人生产力有更深入的了解。比如,这套标准可能包括准时完成任务的百分比、管理者的评分1~10、同事的评分1~10、每个月产出的代码行数、每行代码的平均缺陷数量、不当修复的比率,等等。

  • 不要认为只要有了某种标准(无论单独或者组合)就可以对不同个体的生产力进行细致的鉴别了

    要记住一点:这些个人生产力的标准只是为你找出问题,但是并不会回答这些问题。对这些标准的不当使用,比如用来进行绩效评估,不但会带来管理上的问题,也会造成统计上的问题。

  • 整体的趋势常常比某个时间点上的测量结果更重要

    将这些测量结果在不同个体间进行横向比较往往是得不出任何有意义的结论的。更有用的做法应该是将某个人的测量结果进行纵向分析,看看这个人有没有随着时间的推移而进步。

  • 你要问自己:我测量个人生产力到底是为什么

    在研究环境中,研究员们需要评估不同技术的效率,所以需要测量个人生产力。相对于研究环境,在现实项目中使用同样的测量标准产生的问题就要多得多了。在现实项目环境中,你想要用这些测量标准来做什么?绩效评估?这主意不行,原因刚刚才说过。分配任务?但我所访问过的大部分管理者都说他们不必测量也知道谁是他们团队中的明星成员,这一点我也相信。做预算?不行,不同设计方法导致的差距、不同的任务难度以及其他相关的原因使得我们无法有效利用这些标准来做项目预算。

  一个具体的例子就是 Lotus 1~2~3 第三版和微软 Excel 3.0
开发团队之间的生产率差距。两者都是在1989~1990这个时间段发布的桌面电子表格应用程序。由于很少看到两个公司公布相似项目的数据,所以这
种死对头之间的对比就显得尤其有趣了。这两个项目的数据如下:Excel的工作人员总共消耗了50个工年
,共写了649, 000行代码 。而Lotus
1~2~3消耗了260个工年,共写了400,000行代码
[13]。Excel的团队每个工年的代码产出是13,000行代码。而Lotus的团队每个工年的产出只有1500行代码。两个团队之间的生产力差距超过了8倍,正好证明了我们此前的主张,即团队的生产力也
有差距,并且有着更大量级的差距。

  组织的因素会影响团队生产力的发挥。杰出的组织中个人能力平庸的团队可以超越平庸组织中个人能力杰出的团队。当然,像杰出的组织+杰出的团队或者平庸的组织+平庸的团队这样的组合也不是没有的。在这种时候,团队生产力(或者叫组织生产力)和个人生产力一样相差10倍也就不足为奇了。

  有人曾断言,伟大的程序员写的代码总是更简短。事实上,编程水平和代码的简洁性之间可能有着某种关联,但我现在并不想做这样一个宽泛的结论。我只想说,伟大的程序员总是努力把代码写得更清楚,而结果通常就是更简短的代码。不过有时候,最清楚、最简单和最明显的设计和那些更“巧妙”的设计相比,需要更多一点的代码。在这种情况下,我认为伟大的程序员也会用稍微多一点的代码来避免太过于取巧的设计。无论怎么说,用“每月产出代码行数”来衡量生产力的想法都是有问题的。

  除些之外,很多轶事传闻也支持这种观点。在20世纪80年代中期,当我还在波音公司工作的时候,有个约80个程序员组成的项目组正面临着无法按时完成一项关键任务的风险。这个项目对于波音来说至关重要,所以他们把项目上80个人中的一大半换成了另外1个人,而这位仁兄单枪匹马地完成了所有的编程工
作,并按时交付了软件。我并没有在这个项目组中工作,也不认识这位天才,但是这个故事是一位我所信任的人告诉我的,所以我相信这是真的。

  软件专家们很早就已经发现,团队生产力的差距和个人生产力的差距一样大,是以数量级为单位的。这里有一部分原因是因为物以类聚,人以群分,这一点已经由一次对来自18个组织机构的166个职业程序员的研究证明了。

  生产力=功能点吗

  由于很多研究都指出不同程序员的效率可以有10倍的差距,导致很多人产生了一个想法,那就是测量他们在自己组织内的个人效率。无论如何,这种想法所涉及的测量“活的”程序员的生产力和一般研究中所说的生产力有很大不同。

  巨大的差距带来的负面影响

  “每个月的代码产出”所带来的问题有一部分可以依靠功能点的标准来衡量程序规模。功能点是一套“合成”的测量程序大小的标准。包括输入、输出、查询、文件数量等都被考虑进来,作为确定程序大小的参数。低效的设计/编程风格并不能产生更多的功能点,所以功能点这个标准不涉及代码量的问题。但是它却有
一个更实际的问题,那就是你需要专业人士来计算功能点(很多公司并无这种人才),而且功能点和个人产出的对应也非常粗略,所以无法用于确定程序员的个人生
产力。

  这种差距并不仅限于软件行业。Norm
Augustine的一份研究指出,在各行各业中,包括写作、橄榄球、发明、警务工作等,都存在一个情况,那就是行业中位列前20%的顶尖人才的产出占到
了该行业总产出的50%,无论这些产出是得分、专利、侦破的案件还是软件
。你可以想想看,这还是有道理的。我们都知道,有的学生就是比其他学生优秀,运动员、艺术家甚至家长也是如此。既然这种差别存在于所有人群中,那么软件开发又怎么会例外呢?

在软件工程研究中,被验证得最多的结论就是对于同等经验的两个不同程序员,在效率和质量上可能会有10倍的差距。研究人员还发现,这种差距也适用于团队级别上,也就是说在同一行业内不同的团队也是如此。

  首先发现不同的人在编程生产力上的巨大差距的研究,是1960年由Sackman、Erikson以及Grant三个人完成的。他们研究了工作经验平均在7年的专业程序员,并发现最好和最差的程序员写新代码的时间比为20:1;调试次数是25:1;程序大小是5:1;程序的执行效率是10:1。他们还发现,程序员的经验和代码质量或效率并没有关系。

  生产力=每月产出的代码行数吗

  在现实项目中,个人生产力的标准很难找到一个对项目管理有益而又符合统计学规则的用处。根据我的经验,除了做研究之外,人们想对个人效率进行测量的动机通常来自一些在统计学上不能成立的结论。也就是说,虽然我知道在研究中对个人效率的测量非常有意义,但是我认为在实际项目中却很难找到它的合理用处。

  软件工程研究通常用完成某个任务所需的时间、每小时或每个月能写多少行代码或者其他一些标准来测量生产力。但如果你尝试在商业环境中用这些标准来测量生产力,那就会碰到很多问题。

标签:,

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图