我与一位非常资深的建筑师进行了一次不寻常的简短对话,内容涉及动态和静态语言。他说,公司数据表明使用静态语言可以提高生产率。请注意,这是一家历史悠久的大公司。令我(和其他人)惊讶的是,他使用的指标是添加的代码行。
他迅速消除了有关该指标的反对意见,该反对意见说,在同一公司中,具有相似的文化,业务范围和足够的数据,差异(关于个人的独特情况和能力)充分融合在一起,因此SLOC指标可用于比较企业的生产率。工具和语言。
尽管我不认为此主张得到严格的统计分析的支持,但行业中是否有一些证据可以支持这种思路?
我与一位非常资深的建筑师进行了一次不寻常的简短对话,内容涉及动态和静态语言。他说,公司数据表明使用静态语言可以提高生产率。请注意,这是一家历史悠久的大公司。令我(和其他人)惊讶的是,他使用的指标是添加的代码行。
他迅速消除了有关该指标的反对意见,该反对意见说,在同一公司中,具有相似的文化,业务范围和足够的数据,差异(关于个人的独特情况和能力)充分融合在一起,因此SLOC指标可用于比较企业的生产率。工具和语言。
尽管我不认为此主张得到严格的统计分析的支持,但行业中是否有一些证据可以支持这种思路?
Answers:
高级建筑师的论点可能意味着两件事。
这可能意味着公司中的普通开发人员在使用静态语言时比使用动态语言时会生成更多的代码行。例如,如果15个开发人员使用Java工作六个月,他们将编写100个KLOC,而如果15个开发人员使用Python工作六个月,他们将仅编写50个KLOC。
LOC与生产率之间没有关联。如果要用相同的功能在Java中花费比在Python中多四倍的代码行怎么办?如果是这样,那么根据上述KLOC指标,使用Python可以提高两倍的生产率。
他可能还意味着,与使用动态语言相比,公司中的平均开发人员使用静态语言所生成的代码行更少:十五个开发人员将在六个月内用Java编写100 KLOC或使用Python编写200 KLOC。
尽管通常使用更少的代码行会更好(编写,阅读和维护的代码更少),但仍不清楚Java开发人员与Python开发人员相比具有多少功能。也许与Python开发人员相比,他们只编写了一半的代码,但功能数量却减少了一半?
在这两种情况下,LOC都不是一个有价值的指标,因为相同的功能将无法以相同的代码行翻译成不同的语言。有些语言比较冗长;其他-更紧凑。尽管在某些情况下,紧凑性很有价值,但是并没有通用的规则。一个极端的例子是Brainfuck语言,它具有极高的紧凑性,但由于其可读性而不受欢迎。比较甚至相似的语言也可能很棘手:例如,在花括号时,Java遵循K&R风格,而在C#中,大多数情况下,在遵循正式风格时,左花括号是按自己的方式行的,这导致了人为的C#的LOC的增加。当人们将一种过程语言与一种面向对象的语言或一种功能语言进行比较时,会发生什么呢?
代替使用易于出错的度量标准,高级架构师可以依靠一组可以一起使用时可以衡量生产率的度量标准:每月开发的功能数量,代码库中引入的错误数量以及解决这些错误所花费的时间,技术债务的演变等。这种比较在一开始可能很棘手,因为必须考虑到团队对新语言的不熟悉。一旦团队对它足够熟悉,那么选择就应该基于稳定的指标,并且在很大程度上取决于团队成员自身的偏好。
LOC 在某些狭窄情况下具有价值。例如,它可以提示有关项目和项目部分的大小(并且通常与功能点相关,而通常更易于度量),或者可以指出可能需要进一步注意的方法和类,因为他们的大尺寸。但是,LOC应该谨慎使用,因为想象力不强的事物之间存在某种关联的人们经常滥用它。过去,使用LOC造成的最灾难性的后果是尝试根据每月编写的LOC来衡量单个开发人员的生产率。
SLOC度量标准的问题在于,它测量的是近似的代码编写量,而没有考虑以下因素:
除非另有说明,与许多经过精心设计的可重用代码相比,产生带有大量复制粘贴部分的易于出错且难以维护的意大利面条代码将被认为更具生产力。
因此,SLOC绝对不是衡量生产率的最佳方法。
生产率是针对过程进行衡量的。因此,SLOC可能仅是编码过程的理想选择。
例如,如果您误解了较差的要求,花了五个月的时间生产该软件,将其展示给用户,发现它完全是错误的,然后又花了五个月的时间从头开始对其进行重写,那么您在SLOC中的生产力将相同/月,这是一个团队第一次正确编写代码的原因,例如,因为他们使用了敏捷的流程,可以通过频繁的反馈减少误会。这种明显的平等生产力掩盖了巨大的问题。
因此,衡量软件开发生产率需要考虑到整个过程,包括分析需求,设计要编写的代码,编码,测试,调试以及验证是否满足用户期望。由于所有这些活动都非常不同,所以最好的办法是衡量唯一重要的想法:正在运行的软件,即所生产的软件对用户意味着什么。
存在几种方法:
我必须承认,我个人是静态类型语言的粉丝,因为在我内心深处,我知道它更可靠(多年的编码证明了这一点)。
因此,我可以肯定的一件事是,与非静态类型的语言相比,静态类型的语言能够在编译时防止更多的错误/错误(例如,拼写错误,预期类型不匹配等)。但出于客观考虑,我不敢将其概括为更高的生产率。
也许吧,也许不是。
但是他的论点似乎无效:静态类型语言的生产率提高来自编译器预先捕获的大量错误。
因此,仅靠查看SLOC而不考虑动态类型语言所需的返工是不可能发现这种“更高”生产率的提高的。所以他的比较是不公平的。
可比环境的论点也不成立。某些动态类型化语言允许使用一些高级结构,而这些语言所需的代码要比经典的静态类型化语言之一所需的代码少。因此,您可能需要更少的时间,更少的代码,但是增加了相同的分析,测试和验证开销。因此,通过SLOC衡量生产率会稀释潜在的生产率提高,从而对动态类型语言产生偏见。
关于该主题存在一些最新的学术研究。尽管其中一些人看到了静态类型化的优点,但通常将其限制于特定目的(文档,不良文档代码或API的重用等)。还应使用谨慎的措辞,因为现代IDE已大大降低了与动态键入有关的风险:
这是您的高级架构师的反例:假设我想编写一个由三个类组成的层次结构,其中两个从第三类派生而来,实现一些基类定义的虚函数。
如果我用C ++编写这三个类,那很简单。我声明这些类,在正确的位置使用virtual并完成。
如果我用C编写这三个类,则需要添加很多代码:我需要struct为v-table 定义s,我需要向基类添加v-table指针,我需要添加代码给构造函数以实际设置v表指针,我需要添加代码构造函数以实际调用基类构造函数,我需要添加代码以显式执行内存分配,然后调用构造函数(C ++ new在单个步骤中完成此操作) ),同样,我需要将销毁与后续free()调用分开,以此类推。
关键是,所有这些额外的东西都是毫无头脑的。我可以很快做到。因此,编写C版本所需的时间不会比编写C ++版本所需的时间长。尽管如此,我生产的C代码行比C ++代码多得多。如此之多,就SLOC而言,我似乎在C语言方面的工作效率更高。
与不需要相同数量的样板代码的语言相比,任何需要一定数量的样板代码的语言在SLOC方面的生产率都会更高。
您会发现,SLOC参数从根本上来说是有缺陷的,以至于我实际上会反过来:我将“程序员倾向于以静态语言生成更多SLOC”这一说法表示:“静态语言似乎需要更多内容。样板代码,从而降低生产率”。
我会逆势而为。
我们在工作中跟踪SLoC(尽管我们并不直接在人员配备决策中使用它),而且我已经引起人们争论大多数人在他们的回答中说了什么。实际上,“ LoC无关紧要,因为X技术使我们可以用更少的代码来做更多的事情”或“更好的开发人员编写更好,更短的代码,因此他们编写的内容不比其他任何人都多”。以我的经验(尽管我没有任何硬性数字来支持这些事情),但这些反对意见根本是不正确的。在我自己的时间里,与所有其他有意义的衡量他们作为工程师的整体“能力”的衡量标准相比,我发现开发人员在代码生产的速度和质量上有着明显的相关性。为了对上述各种参数提供一些反例:
这是我的总体总结,顺便说一句。我发现,无论技术堆栈或项目类型如何,大多数开发人员都有自己的节奏,这就是他们所遵循的节奏。如果一种语言具有许多使开发人员的代码更有效的功能,那么这对企业来说是一个很大的福音,但这并不意味着他们会减少编写的代码。相反,它们可以更快地完成功能,并迅速转移到新代码上。同样,最终结果是他们对代码的评分主要取决于他们的技能,而较少取决于他们的技术堆栈。实际上,由于这个原因,我通常希望技术堆栈对票证和功能的开发速度产生更大的影响,而不是对人员编码的速度产生影响。
话虽如此,代码写入率和票证关闭率都不是生产率的完美衡量标准,这就是为什么我们不直接根据SLoC做出人员配备决策的原因。相反,它是该过程的一部分,并且使用尽可能多的数据点来进行员工评估。我要说的是,您的建筑师当然并不疯狂。
一个例外
我同意的一个例外是样板代码的可能性。如果要从一个类(或其他任何类)到另一个类进行大量复制和粘贴,以使其正常运行,那么显然会扭曲度量标准。如果您拥有可以为您自动生成大量代码的工具,也是如此。但是,我认为这些通常是例外而不是规则。如果您的开发人员花费大量时间来复制样板代码以开始使用,那么您使用的是错误的技术集。如果他们实际上是在编写代码,即使它是相当重复的,那么我希望这只会使任何度量值偏小:在编写代码时,大多数时候,我们受到问题思考速度的限制,而不是比我们打字的速度快。即使编写相对重复的代码,
显然,以上所有内容都是基于我个人的经验。您的行驶里程可能会有所不同,显然我是少数。随时不同意。总而言之:
我发现编码的速度更多地取决于您思考问题的速度,然后再考虑其他问题。结果,我发现编码率是生产率的一个不错的衡量标准,即使是跨技术集,也只有少数可能的例外。
虽然我正在追赶潮流。我认为需要强调对程序员行为的影响。
使用SLOC作为生产手段对程序员的士气有毒害作用。当您的团队/公司中的任何工程师意识到对他们进行SLOC评估时,都会发生几件事:
我不能足够强调应力,以鼓舞士气有多强,因为我已经看到它在两家不同的公司发生过两次。无论您拥有哪种看似有效的用例,我都认为,即使只有很小的机会被发现使用它,也不可能对您的团队/公司造成影响。即使在某些情况下,所写的行数与有用功能的数量之间可能存在相关性,但它会鼓励程序员中的所有错误行为,并且向其发送消息的质量并不重要。
通常,它不是衡量生产率的有效方法。较小的代码通常比较大的代码更好,因此,生产力更高的开发人员通常产生较少的代码。生产力在调试中受到最大的打击;高效的开发人员很少花时间进行调试。
静态类型的语言更具生产力(如果您控制语言之间的所有其他差异),因为明智地使用它们会减少调试时间,并在编译阶段捕获错误,从而可以更快地进行修复。
您可以用来比较开发人员在不同语言之间的生产率的唯一度量标准是不比较两种语言之间的代码的度量标准。有些语言非常冗长(COBOL代表了传统的胜利),而另一些语言则需要几个步骤来完成您可以在一行代码中完成的工作(汇编或几乎所有其他代码)。即使只比较活动的代码行(即,不计算声明,而仅计算涉及某些操作的代码),您仍然可以使结果倾斜。
您也许可以为变化率辩护。即添加了代码行,比较了同一时间段内的生产率斜率。但是,这并不能说明代码行中的负面变化。例如,您继承了一个到处都有复制和粘贴代码的项目。您可以执行一些快速简便的重构以减少重复的代码块的数量-根据定义,您的斜率为负。
认真地说,比较团队/语言的生产力是没有意义的,因为有太多其他因素会影响团队的生产力,因此您不能从中得出有意义的结论。
我参与了一个项目,该项目的基础设施非常脆弱,工具已经过时。该项目是在Java上构建的,并带有一个单页应用程序,但是托管在portlet容器中却没有明显的好处。进行简单的更改所花费的时间荒谬地长。如果您将所有结论都基于该特定项目,则可能会得出Java错误或Single Page Apps错误的结论。都不是真的。丑陋的项目应该替换的系统是基于C#和WebForms构建的。当我们提出扩展现有应用程序来满足客户需求的业务案例时,我们的生产力猛增。这是否意味着紧密耦合的WebForms应用程序优越?您只能针对这种特殊情况得出结论并且不会扩展到整个世界。这仅是有意义的,因为现有的应用程序具有足够的成熟度可以扩展。
就您在比较完整的项目基础结构而言,甚至在问题跟踪系统中比较解决项目的比率也是有缺陷的。使用的库和框架可以加快或减慢进度。您可能需要很少的惯性就处于启动阶段,而您“胜于”的项目处于维护阶段,因此新凭单的数量相对较少。绝不会进行类似事物的比较。