理想的 PR 长度为 50 行

2024-04-25 11:20
文章标签 长度 50 理想 pr

本文主要是介绍理想的 PR 长度为 50 行,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

原文:Greg Foster - 2023.07.25

大多数工程师都有一种直觉,那就是小的代码更改总是比大的更好。逻辑论证也很简单——小的 pull requests 更容易 review,出现错误的可能性更小,从构思到部署的速度也更快。

关于这个问题,我很喜欢几篇论文 - 如果想进一步阅读,可以参考:

  • Small patches get in!
  • Do small code changes merge faster? A multi-language empirical investigation

但是,什么样的更改才算小呢?PR 会不会 小?如果一个 PR 比一个大的 PR 更好,那么 好多少 呢?

主张:理想的 PR 长度为 50 行

通过数据分析,我们发现,理想的代码更改应该是 50 行。

50 行代码更改的 review 和合并速度比 250 行的快大约 40%。它们被撤销的可能性比 250 行的小 15%,每行更改的 review 评论数量多 40%。如果你的平均 PR 有 50 行,那么你发布的总代码可能比编写 200 多行 PR 的队友多 40%。

50 行是速度、review 评论、撤销率和总编码量的最佳选择。如果你愿意接受一个范围,我会推荐每个 PR 25-100 行。根据数据,我们发现 PR 越小,review 时间、合并时间和每行评论的时间都会变得更好。但是,也有一个限制:如果少于 25 行,就会开始遭受更高的撤销率,以及更低的代码发布总量。

我们来讨论一下为什么,并用一些数据来支持这一说法。

我们的样本集

(注:Graphite 是一个 PR 增强工具。)

本文中所有基于数据的陈述,都是使用与 Graphite 同步的私有/公开 PRs 和仓库得出的。为了找出理想的 PR 大小,我查看了四个主要指标,以及它们与 PR 大小的相关性:

  • review/合并时间
  • 撤销率
  • 行内评论的平均数量
  • 一年内改变的代码总量

注意事项

与所有收集的数据一样,从数字推断含义时,有一些需要注意的事项:

  • 我使用了不一致的、非线性的桶大小,对应于直观的 PR 大小范围。线性桶将过于精细,而指数桶大小会丧失太多细节。
  • 我使用的是中位数 PR 大小,而不是平均 PR 大小,以避免异常的重构偏离数据。
  • 定义撤销的 PR 是标题中包含 “Revert” 一词的 PR。这个假设似乎是安全的,因为生成的 GitHub 撤销,会自动在标题前加上这个词。
  • 我们发现 Graphite 用户通常会创建较小的 PR,因为许多组织使用基于主干的开发风格(这种风格鼓励创建较小的 PR)。

review 时间和合并时间

让我们深入研究数据。从 review 时间和合并时间开始,我们可以看到最小的 PR 比 2000-5000 行的 PR 快近五倍。直观上,这是有道理的 - 更小的 PR 意味着更少的代码行,更少的代码意味着破坏性或细致的更改的机会更小,这反过来又导致了更快的 review。

令人着迷的是,超过 5k 行后,PR 又开始变得更快了。我只能假设这是盲目的 review 通过、被认为安全的重构、包的添加或生成更改的组合;也许当作者和 review 者甚至无法滚动到更改的底部时,他们都会开始耸耸肩。

请注意,假设我们更关心每个 PR 的时间,而不是每行的时间。如果我们关心的是尽快完成一个 PR,数据显示要尽可能地缩小它。但如果希望尽快完成大量的代码,那么一个 2000 行的 PR 大约每小时合并 12 行,而一个 10 行的 PR 大约每小时合并 0.25-2 行。

在这里插入图片描述

按 PR 大小的撤销率(Revert)

撤销率显示了同样的高级结论:较小的 PR 比较大的 PR 撤销的次数更少,被撤销次数最少的 PR 是那些 25-50 行的。但再一次,图的边缘很有趣。不足 10 行的 PR 被撤销的次数明显多于 10-100 行的 PR。如果必须猜测,我会说不足 10 行的 PR 可能涉及到一些危险的配置更改,但我很好奇,如果在对编程语言进行标准化(每种语言分别统计)后,这个发现是否仍然成立。

一旦 PR 开始超过 1 万行代码,它们似乎变得“更安全”了。我怀疑这是因为 PR 大小的极端包括重构,可能包含更少的功能更改,因此破坏的机会稍微减小。或者,由于情绪抵触和合并冲突,工程师可能会对撤销超过 1 万行的 PR 变得越来越不情愿。

在这里插入图片描述

按 PR 大小划分的平均行内评论数量

取决于你的优化的目标是什么(快速合并还是深入的代码 review ),可以选择是否将 PR 分割成更小的变更集合。如果想在单个 PR 上获得最多的反馈,那么选择 1k-2k 行代码。如果想获得盲目 review 通过的最高机会,保持在 10 行以下。当你所关心的只是尽可能少的争论就能推进一个特定更改时,了解此信息是有用的。

我们在这里也看到,大的 PR 开始逐渐减少参与度。你的 review 者愿意阅读的代码量有一个实际的限制——我怀疑 2000 行是从“阅读”一个 PR 变成“浏览”一个 PR 的点。

在这里插入图片描述

如果你关心的是最大化代码在长期内的参与度和反馈,尽可能地写小 PR。它们更容易理解,并且可以平均在每 39 行代码中拥有一条评论。另一方面,如果你讨厌书面反馈,那么让 PR 超过 1 万行,你将开始在每改动 6000 行代码时只收到零星的评论——不过,对此要持保留态度,因为人们很少为了获得反馈或他人参与而提交 PR。

在这里插入图片描述

总代码产出

有些人可能会想,写小的 PR 是否会导致总的代码产出减少。我们都希望能高效地工作,但有时需要提高代码产量。持续写小于 20 行的 PR 将对你的净编码能力产生显著影响——但有趣的是,写大于 100 行的 PR 也会产生影响。最高产量的编码者和仓库的中位数更改大小只有 40-80 行。我怀疑这是因为代码量等于更改大小 * 更改速度。更改太小,更快的合并时间并不能弥补。太大,你开始被更慢的 review 和合并周期拖累。

在这里插入图片描述
在这里插入图片描述

结论

一般来说,科技公司团队中的普通开发者应该以 50 行的中位数 PR 大小为目标——这通常是我们在 Graphite 坚持的 PR 大小。显然,这带来了一些在上文中讨论过的边缘情况,特定的更改可能需要在大小上做出调整,但是要知道,这样做可能会对 review 质量、速度以及更改被撤销方面产生显著的成本。

这篇关于理想的 PR 长度为 50 行的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/934539

相关文章

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

Java实现按字节长度截取字符串

《Java实现按字节长度截取字符串》在Java中,由于字符串可能包含多字节字符,直接按字节长度截取可能会导致乱码或截取不准确的问题,下面我们就来看看几种按字节长度截取字符串的方法吧... 目录方法一:使用String的getBytes方法方法二:指定字符编码处理方法三:更精确的字符编码处理使用示例注意事项方

PR曲线——一个更敏感的性能评估工具

在不均衡数据集的情况下,精确率-召回率(Precision-Recall, PR)曲线是一种非常有用的工具,因为它提供了比传统的ROC曲线更准确的性能评估。以下是PR曲线在不均衡数据情况下的一些作用: 关注少数类:在不均衡数据集中,少数类的样本数量远少于多数类。PR曲线通过关注少数类(通常是正类)的性能来弥补这一点,因为它直接评估模型在识别正类方面的能力。 精确率与召回率的平衡:精确率(Pr

【附答案】C/C++ 最常见50道面试题

文章目录 面试题 1:深入探讨变量的声明与定义的区别面试题 2:编写比较“零值”的`if`语句面试题 3:深入理解`sizeof`与`strlen`的差异面试题 4:解析C与C++中`static`关键字的不同用途面试题 5:比较C语言的`malloc`与C++的`new`面试题 6:实现一个“标准”的`MIN`宏面试题 7:指针是否可以是`volatile`面试题 8:探讨`a`和`&a`

day-50 求出最长好子序列 I

思路 二维dp,dp[i][h]表示nums[i] 结尾,且有不超过 h 个下标满足条件的最长好子序列的长度(0<=h<=k),二维数组dp初始值全为1 解题过程 状态转换方程: 1.nums[i]==nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h]+1) 2.nums[i]!=nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h-1

Pr 入门系列之二:导入与管理素材(下)

◆  ◆  ◆ 管理素材 导入素材后,项目面板中每一个媒体都只是原始素材的“链接”。 所以,视频编辑过程中一般情况下都不会破坏原始素材。 1、在不同视图模式下组织素材 项目面板提供了三大视图 View供选用:列表视图、图标视图以及自由格式视图。 A. 锁定 B. 列表视图 C. 图标视图 D. 自由格式视图 E. 缩放滑块 F. 排序图标 G. 自动匹配序列 H. 查找 I. 新建素材箱 J.

Java应用对接pinpoint监控工具的时候,应用名称长度超出限制而导致接入失败

一、背景 java应用需要接入pinpoint,同一个虚拟机上的其他应用接入成功,唯独本应用不行。 首先排除是pinpoint agent的问题,因为其他应用都正常。 然后,我就对比二者的启动脚本。 -javaagent:/opt/pinpoint/pinpoint-bootstrap.jar -Dpinpoint.agentId=DA301004_17 -Dpinpoint.applic

2300年都无人能知有长度不同的伪≌射线

黄小宁 【摘要】自有射线概念后的2300年里一直无人能知有长度不同的射线。保距变换和≌图概念是能放大无穷大倍的思维望远镜使人能一下子看到有长度不同的伪重合、伪≌射线。 变量x所取各数也均由x代表,x代表其变域(x所有能取的数组成的集)内任一元。设集A={x}表A各元均由x代表,{x}中变量x的变域是A。其余类推。“实数集”R所有非负元x≥0组成R+={x≥0},这里的x≥0不是表示x可取一切非负

50. Pow(x,n)

题目: 解答: 主要是求 n &gt; 0 n &gt; 0 n>0 的情况的计算,其他时候,可以通过转换得到。 而 n &gt; 0 n &gt; 0 n>0 的情况下, ​ n = a 0 2 0 + a 1 2 1 + a 2 2 2 … a m 2 m n = a_0 2^0 + a_1 2^1 + a_2 2^2 \ldots a_m 2^m n=a0​20+a1​21