科学代码是一个足以忽略普通编码标准的领域吗?


21

最近,我一直在努力思考以下事实。

一方面,对于所谓的“健康”,“干净”,“编写良好”等代码,有大量的编码准则和标准。参见似乎也在此处广泛讨论的“清洁代码”。规则示例:7行长方法和1或2级缩进。不遵循的代码将因可维护性差而死亡。

另一方面,我可以使用OpenCV,OpenCascade,VTK等。这是科学代码。他们有2页长的方法(我自己说),OpenCascade的方法或类分为10个文件(这里没有笑话),VTK有时也很混乱。然而,这些项目繁荣起来,得到了维护和广泛使用!

哪里有收获?我们是否被允许以一种可以正常工作的方式编写科学的,繁重的代码,并且我们可以对其进行维护?您是否为此类项目制定了一套单独的标准?

也许这是一个幼稚的问题,但是我似乎在一个编程空白中试图建立一套规则,该如何做和不做某事,这就是我在高中时被教导要工作的方式。自从我毕业以来,我对所要做的事情(主要是编程)几乎没有指导性的支持-没人会教。


25
不,不是,但是大多数科学家没有经过工程培训就可以更好地了解。
砸死了机器人

4
在已经存在了一段时间的任何项目中,您都会发现大量的代码编写得很差,但是看起来效果很好,没有人会费心去清理它。有时是因为标准和模式会随着时间的推移而发展,有时是因为标准不是统一实施的,有时是因为添加新功能比返回并重构一段有效但效果不佳的代码要有趣得多。记录下来。
贾斯汀·凯夫

2
@JustinCaveL或:“如果没有损坏,请不要修复它。” 特别适用于只写代码。另请参见plaza.ufl.edu/johnaris/PDFs/ProblemSolvingFlowChart.pdf
Robert Harvey

您肯定会发现我之前的问题是相关的:programmers.stackexchange.com/q/266388/620
rwong

8
同胞回答者:这个问题涉及到代码基础开放源代码库,用于计算密集型任务中的一个或多个科学领域。这个问题与一次性代码无关请稍等片刻,以确保您掌握所有突出显示的方面,然后再写答案。谢谢。
rwong

Answers:


28

科学代码是一个足以忽略普通编码标准的领域吗?

不,这不对。

研究代码通常是“扔掉”的,不是由具有背景知识的开发人员撰写的,无论他们的学术实力如何。我写的一些研究代码会让我流泪。但这有效!

要考虑的一件事是,项目的看门人将推动所包含的内容。如果一个大型项目最初是作为一个学术/研究代码项目开始的,但是最终可以正常工作,现在又一团糟,那么有人必须主动进行重构。

重构不引起问题的现有代码需要大量工作。尤其是在所有特定于域或没有测试的情况下。您会发现OpenCV的风格指南非常全面,即使不是完美的。追溯地将其应用于所有现有代码吗?那是..不是为了胆小的人。

如果所有代码都能正常工作,这将更加困难。因为它没有坏。为什么要解决?

然而,这些项目繁荣起来,得到了维护和广泛使用!

从某种意义上说,这就是答案。工作代码仍然有用,因此更有可能得到维护。

可能是一团糟,尤其是最初的情况。这些项目中的某些项目可能始于“一站式”项目,“永远不需要重复使用,可以将其丢弃”。

还应考虑到,如果您要实现复杂的算法,那么使用更大的方法可能更有意义,因为您(以及其他熟悉科学方面的人)可以从概念上更好地理解算法。我的论文工作与优化有关。将主要算法逻辑作为一种方法要比将其试图分解要容易得多。它确实违反了“每种方法7行”的规则,但是这也意味着另一位研究人员可以查看我的代码,并更快地了解我对该算法的修改。

如果将此实现抽象化并设计得当,则这种透明度将对非程序员失去。

致答题者:这个问题涉及一个或多个科学领域中用于计算密集型任务的开源库的代码库。这个问题与一次性代码无关。请稍等片刻,以确保您掌握所有突出显示的方面,然后再写答案。

我认为人们经常有这样一个想法,即所有开放源代码项目都始于:“嘿,我对一个将被成千上万的人广泛使用并广受欢迎的库有一个好主意”,然后每个项目都是这样。

现实情况是,许多项目已经启动并死亡。极少的项目将其“实现”到OpenCV或VTK等的水平。

OpenCV是Intel的一个研究项目。维基百科将其描述为“一系列项目”的一部分。它的第一个非beta版本是2006 ,也就是它首次启动后的七年。我怀疑最初的目标是有意义的beta版本,而不是完美的代码。

此外,OpenCV的“所有权”已发生重大变化。除非所有责任方采用完全相同的标准并在项目进行期间保持标准,否则这将使标准发生更改。

我还应该指出,OpenCV大约已经发布了好几年,而《清洁代码》的灵感源于《敏捷宣言》的发布(而VTK接近10)。VTK在发布Clean Code之前的17年开始(OpenCV在9年前“仅”发布)。


2
我在2004年就一直在使用OpenCV,那真是太糟糕了。Willow Garage(新所有者)通过将几乎所有内容都转换为C ++取得了出色的成绩。实际上,它是由良好代码组成的为数不多的科学图书馆之一。
nimcap

15

科学家不是开发商。他们的工作不是自己编写代码。他们的工作是解决问题,而编程只是他们可能使用的工具之一。

专业开发人员编写的大多数企业代码都是一团糟。此代码大多数不使用设计模式或滥用它们。大多数评论都是TheDailyWTF的候选人。因此,既然在我们自己的行业中,我们会从工作是编写代码的人那里看到这样的结果,那么您对工作不是编写程序的人有什么期望?

实际的专业开发人员在其职业生涯中所学到的所有实践都会使科学家受益吗?绝对。每个科学家是否有可能在其生命中花费五到十年来学习软件开发?可能不会。因此,代码质量保持不变。

另一个因素是文化。如果您的夫妇不写干净的代码,那您为什么呢?由于没有人在乎,因此您实际上并不愿意付出额外的努力。

最后,大多数科学法规的寿命相对较短。您为特定的研究编写代码,完成研究后,您就不会重复使用代码。一旦有了这种习惯,就很难在可重用的库(例如引用的库和一次性代码)之间有所作为。


“他们的工作本身不是编写代码。他们的工作是解决问题” –请注意,从技术上讲,开发人员的工作也不是编写代码。和科学家一样,他/她的工作是解决问题。我不包括有报酬来保暖椅子的软件工厂和代码猴子,但是根据定义,他们也不太关心干净的代码,因此它们与这个问题无关:)
Andres F.

8

忽视?否。重新考虑并调整?当然。许多科学代码是数学密集型的并且对性能至关重要。诸如函数调用的开销之类的事情实际上可能会成为问题,因此您可能会得到比典型的商业应用程序更深层的嵌套结构。这并不意味着您应该首先着手进行一千个微优化。您仍然应该专注于选择正确的算法,并且仅进行可以衡量其效果的优化。

其中一些差异是显而易见的且微不足道的。编码指南通常会要求选择有意义的变量名,并且单个字母的名称会立即受到怀疑。科学应用程序仍然需要有意义的变量名,但有时最有意义的名称是单个字母,指代众所周知的方程式中的变量。


4
+1为变量命名注释。当我在学校的时候,我为各个部门进行了一些自由编程,在统计和数学部门,我被“强烈鼓励”使用像这样的变量名AjT0因为那样就是在我要转换为代码的函数中命名变量的方式。使用类似correlationIndexstartTime会使您发牢骚。
TMN

4

现有的所有答案已全面涵盖了这个问题。但是,我想指出像OpenCV之类的东西之间的真正对立,而不是说根据良好商业惯例(代码完成,整洁代码,SOLID等)开发的代码之间的对立。

通常,使源代码成为KISS有很多商业利益- “保持简单,愚蠢”。还有一个与之相关的YAGNI- “您将不需要它”。

不幸的是,对于科学领域中计算量大的软件,源代码很少简单或精简


传统上,OpenCV缺乏通用性(大量的代码重复以支持不同的选项),而VTK则遭受过多的通用性(模板)。

早期,OpenCV的某些部分最初是用C语言开发的。后来,OpenCV采用了我们今天熟悉的C ++ API。重写了一些算法以利用C ++接口(抽象基类)和C ++模板。其他算法只是原始C代码的包装器。这些代码的残余可以在“ imgproc”模块中找到。

OpenCV包含许多SIMD编程(向量化)。迄今为止,使用C ++进行SIMD编程仍然需要使用内部函数(intel.com)(arm.com)

SIMD内部函数的读取方式类似于汇编语言,不同之处在于,编译器负责变量的寄存器分配,并且允许编译器自由地交换指令顺序以提高性能。使用SIMD内部函数编写的算法维护成本很高。这就是我提到我先前提出的一个问题的原因-SIMD编程代码库的维护成本

一个不进行SIMD编程的人可能会轻易地认为,SIMD可以被优雅地封装,并且不再需要低级SIMD编程。这实际上与事实相去甚远。我会挑战任何人尝试在SIMD中实现有用的算法(而不是分形),并看到这些拟议封装中的使用困难。


当我尝试分析为什么计算软件不能成为KISS或YAGNI时,下面是一长串想法。但是,所有这些想法都过于笼统,它们似乎不支持上述观点。

主要的影响因素有:

  • 软件性能
  • 需要支持许多算法选项和权衡
  • 需要支持许多不同的硬件平台和编译器
    • 这与软件性能问题并存-对于许多硬件平台和编译器来说,性能都需要良好。
  • 由于缺乏资源,缺乏能在不影响其他因素的情况下提高代码质量的知识渊博的人等原因,缺乏正在进行的代码库现代化
    • 开源项目遭受公地悲剧
    • 接受资助的开源项目必须满足特定的可交付成果-代码质量通常不属于其中。
    • 特别是,甚至缺乏知识渊博的人,他们可以提出或建议逐步提高代码质量。这是“缺少眼球”的问题 -许多人从代码中受益,但是很少有人花时间阅读代码。
  • 历史上缺乏代码质量门,例如代码审查,单元测试,静态分析等。
    • 对于大型项目,这些代码质量门不仅仅是手动步骤-每个都需要基础结构(基于Web的系统,单元测试系统,构建自动化系统等)。

以上几个促成因素与商业软件开发息息相关

  • 通常,商业软件不需要处理计算软件中所见的相同高数据吞吐量。
  • 商业软件可以绑定到单个操作系统和计算机体系结构。
  • 商业软件在决定要包含的功能时可以节俭。实际上,除非有良好的业务案例,否则商务软件开发会鼓励管理人员对新功能拒绝。
    • 内部业务软件的用户可以接受培训,以不同的方式做事,而无需进行代码更改。
    • 如果商业商务软件由于一项缺失的功能而失去了一位客户,但是由于改进的易用性和易用性而获得了两个新客户(请参阅“选择的悖论”),则总的来说,这是净收益-这是一件好事缺少这一功能的事情。
  • 持续的收入流为业务软件提供了支持,因此它有能力将其一部分用于持续的代码库现代化。

1
您在表中提出了很多要点,这些要点似乎都与问题无关。
马丁·马特

@MartinMaat如果您对此问题有积极的看法,请写下您自己的答案。
rwong

3

科学代码是一个足以忽略普通编码标准的领域吗?

这取决于您所谓的“通用编码标准”。我不会将敏捷的极端称为“常见”。尤其是,在数字/科学编程领域中,认为具有八行长而又太长的函数或具有两个以上缩进级别以至于太复杂的函数是可笑的标准。

一个非常简单的矩阵乘以矩阵函数超过七行,并且具有三个缩进级别。该功能将变得比应该关注效率的情况复杂得多。这是一种常见的操作,因此效率很重要。将其分解成碎片是您不希望做的。矩阵分解将变得更加复杂。


2
“敏捷”与编码标准无关。
砸碎了机器人

@StevenBurnap-当然可以。查看“清洁代码”。它具有大量的编码标准。
大卫·哈门

1
具有很多编码标准的干净代码是一个不好的说法。敏捷宣言可能与编码标准没有任何关系,但是敏捷确实可以提高灵活性,并能响应变更并坚持编码标准或最佳实践来支持这一点。因此,以一种非常间接和谨慎的方式,敏捷可能与编码标准没有任何关系,但是编码标准确实与敏捷有很多关系。
Marjan Venema

1

我决定将其发布为新答案,因为这是完全不同的观点。

让我们看一下在计算机视觉和图像理解方面我认为是“干净的代码”的代码示例:

https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/modules/photo/src/seamless_cloning_impl.cpp

对于那些熟悉MATLAB和科学计算的人来说,C ++中的代码几乎与最简洁的MATLAB代码一样简洁。


现在我们要问,为什么没有将整个库代码库(在此示例中为OpenCV)编写为与此代码示例相同的标准?


我们必须将大型科学图书馆的代码库分层抽象级别

底层,您实际上是在重新实现加法和减法。或者,从字面上将每个操作重新映射到每个平台上最快的实现。

https://github.com/opencv/opencv/blob/master/modules/core/src/hal_replacement.hpp

中间层,我们找到了“最脏”的代码,其中大约80%-90%的CPU执行时间都花在了上面。(同样,如果我们将软件开发工作与科学研究分开计算,则大约80%-90%的开发工作是花在中层上的。)

高层次来看,我们拥有研究人员编写的最简洁的代码。


需要在源代码组织方面有出色的表现,以确保这些级别不会混淆。这超出了编码标准,更多地与开源管理有关

例如,有时决定将一个开源项目分成两个部分。您无法通过代码提交来使这些事情发生。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.