聪明的与洞察力代码

2021-06-07 12:05:59

“不要写聪明的代码。”为什么不? “因为很难理解。”那些说这个想想聪明的代码,如duff的设备:

发送(从,计算)注册短*,*注册计数; {寄存器n =(count + 7)/ 8;切换(计数%8){case 0:do {* to = * from ++;案例7:*到= *来自++;案例6:*到= *来自++;案例5:*到= *来自++;案例4:*到= *来自++;案例3:*到= *来自++;案例2:*到= *来自++;案例1:*到= *来自++; }而( - n> 0); }}

这段代码是“聪明”,因为它利用了关于语言的知识,在这种情况下,秋季的特点。巧妙的代码还可以利用有关操作环境或特殊主题的知识,如绑定绑定。传统的智慧说,这个聪明的代码是“坏”。

有一种第二种“巧妙代码”:利用关于问题的知识的代码。考虑出生日期对美国的所有300万人进行分类。 “简单”解决方案是使用Quicksort,其具有〜30的“log 2因子”。 “聪明”的解决方案是利用美国的每个人120岁,而不是桶装〜45000桶。这将列表排列在单个通行证中,这是一个幅度的级数更有效。

这种聪明的代码也可以更容易理解。由于您解决了比常规情况更简单的问题,您可以编写更少的代码并更清晰。这通常最终是特定于高度域的,但如果列表的每个元素是唯一的,则Python中的一个简单示例是测试:

我们谈论聪明才智,好像它只是糟糕,如“聪明的代码更难调试”。那太过分了。聪明可能会导致更快,更安全,更清晰的代码。我打电话给这类聪明“有洞察力”来区分它们。

洞察可以更快,更简单,更安全地制作代码。但它也是脆弱的:洞察力只有工作,因为他们在问题中利用了一些财产。如果问题发生变化,甚至轻微,洞察力解决可能会破裂。我们无法调整我们的实现IS_UNIQUE以检查每个元素是否出现两次。 1 Insight通常是不可拓展的:问题的巧妙解决方案看起来与类似的问题看起来都不像聪明的解决方案。

这导致了富有洞察力的缩放性问题:它是“只读”。您需要大量的默契知识,始终如一地提出有用的见解,这不是人之间转移的东西。我可以找到一个问题的洞察力解决问题,然后在erturbs问题时找到新的洞察力。但如果我离开这个项目,那么团队的其余部分可能无法做到这一点。他们可能没有相同的技能或背景信息,不能以同样的方式聪明。 2

这并不意味着洞察力是坏事。它只是意味着我们需要在我们的项目中解释它。要求变更将不成比例地影响富有洞察力的代码。记录码码的哪些部分使用富有洞察力代码以及我们将其基础的场所进行了有意义。我猜我们也可以通过重新审视房屋并看到任何改变来调试富有洞察力的代码,但我在实践中没有尝试过这一点。

几年后,有一串关于“以$语言击打C的散文”,从击败C 8线哈尔克尔:WC。与Haskell一起使用的Chris Penner能够编写一个比Mac默认WC速度快〜2x的Wordcount工具。然而,他花了很多工作来到达那里:

它可能不会立即明显多种像这样的作品,但是有一类计数的问题,所有这些问题都陷入了这样的同一类别,幸运的是我之前的工作。基本上,我们需要计算给定不变性从序列的开始到结束的给定不变的次数。我之前已经推广了这类长嘴,并命名它们的助焊剂。我们需要做的是计算我们从空格的空格的字符更改的次数。我们可能会用助焊剂单个本身表达这一点,但由于我们需要如此谨慎地对严格和性能来说,我将为我们的目的定义一定程度的磁共管道的定制版本。

Penner没有用Haskell击败C,他用聪明的Haskell击败了C.专家Haskeller可能有足够的洞察HyperOptimize Haskell,但我们不能指望平均哈斯克勒拥有这种专业知识。此外,我们将富有洞察力的Haskell与常规C进行比较。使用的标准WC Penner根本没有优化。当有人熟悉C程序时,他们加速了100倍。洞察力的Haskell比常规C更快,而不是洞察力的C.

这不是折扣Ponner的工作:这是一个令人印象深刻的哈斯克尔的优势。但这是洞察力如何分析的一个很好的例子。读他的作品很容易,并相信Haskell真的比C更快,完全缺少混淆因素。

我应该清楚这个问题并不局限于特定语言。专家C程序员认为他们不需要内存安全,专家克罗夫斯主义者认为,无论其论证的其他优点如何,静态类型都不会帮助它们,他们都从专家的角度争论。专家更容易解决问题。这并不意味着他们的争论是错误的,也不是指他们不应该依赖他们的洞察力。这只是我们必须有意识的东西。

我把它设置为“聪明的是关于代码诡计,洞察力是关于问题诡计”。这不太真实。有时您需要洞察力首先编写代码,因为您无法以“显着”方式编码解决方案。例如,使用基于物业的测试输入生成器。您如何生成一个列表,其中第一个元素是最低值的?在假设中,您可以使用过滤器谓词进行操作:

但这将过滤掉太多示例,导致Heathchecks和Long Runtims失败。您应该编写手动生成器:

几乎每个有趣的发电机都需要一些洞察力。这对刚刚与PBT开始的人来说是一个很大的障碍,它伤害了采用。

这与正式规格语言特别糟糕。他们很多都专注于易于验证,以便轻松表达事物。例如,棱镜可以验证概率属性......但没有数组或函数。您需要各种各样的见解将您的问题克切到语言困境中。模拟两名工作者从队列中删除消息,我使用了以下洞察:

因为我正在建模总延迟,所以我不需要跟踪单个消息。

所有消息都无法区分,因此消息队列仅是其中的消息数。 “处理”一条消息只是意味着递减计数器。

我可以代表通过概率递减计数器来处理不同时间的不同消息。

如果所有工人都无法区分,我可以代表多个工人作为一个步骤,其中包括删除最多消息的不同机会,并且这些机会是二项式系数。

dtmconst int n; //留下的任务编制工人数:[0..n] init n;队列:[0..n] init 0; [eNqueue](队列左侧) - > 0.5 :(队列' =队列+ 1)+ 0.5:真; [工人](左> = 1& queue = 1) - > 0.5 :(左' =左 - 1)& (队列' =队列 - 1)+ 0.5:真; [工人](左和gt; 1&队列> 1) - > 0.25 :(左' =左2)& (队列' =队列 - 2)+ 0.5 :(左' =左 - 1)& (队列' =队列 - 1)+ 0.25:真; [](左= 0) - >真; endmodule.

规格很漂亮但脆弱。如果我想建模多个消息优先级,那么我必须从头开始。我有信心我可以想出一些工作的东西,但我需要新的见解。与在Python中编写模拟比较:我不会有所有棱镜的保证,我不会有相同的分析能力,但我也不需要富有洞察力。我只能代表一个列表的消息队列。完毕。

一方面,有像阵列这样的东西会使棱镜规格变得更加容易。另一方面,棱镜的简单性是我们为其途径支付的价格。也许我们不能制定强大的规格语言,这些语言不需要洞察。这是一种采用障碍,但没有绕过它。

我认为一个良好的中间地面可能是添加表达功能,而是限制你可以与他们验证的东西。如此,如将数组添加到棱镜,但使用它们的任何规范都不能使用完整的验证套件,只有一个子集。这样,人们可以用更具表现力的规格建立专业知识,并且当他们需要高级验证时,他们就足以写入洞察力规范。

我被认为是这种区别,因为我觉得我们对“巧妙代码”的讨论太受约束了。虽然“纯粹”聪明是我们应该劝阻的事情,但“洞察力”聪明似乎是我们应该以不同的方式接近的东西。这是往往是必要的,使事情工作,并且可以比同等的“无聊”代码更好。重要的是要注意使用洞察力以及使用洞察力的上下文限制,如果他们改变会发生什么。

我们还应该了解它如何影响我们对软件的讨论。 “这个工具需要洞察力的”这个工具“涉及”这个工具很难学习“?对不同领域的洞察力不同,或者在不同的专业知识中有不同的期望吗?某些编码方法是否依赖于洞察力而不是其他方法,这会影响易于提升性吗?

有办法教洞察力吗? 人们在他们开发某些东西的专业知识时获得一些基线洞察力,但我不知道您是否可以教授洞察力。 我的肠子说不,但我觉得我在这里错了。 这并不意味着没有富有洞察力的解决方案,只是它看起来与我们已经拥有的那样不同。 [返回] 交谈也是如此。 Insight是具体的域名。 我的替换很容易在我不是的其他域名的洞察力,并找到一个完全不同的解决方案。 这表明聪明的是小型,紧密编织的团队的资产,每个人都同时有见解。 [返回]