在我看来,可以为静态源代码分析定义一个上下文,其中包括可以产生相对价值的规则。我知道这不是物理意义上的,因为源代码没有“能量”,但是我敢打赌,精湛的学术界已经做出了类似的努力。有谁知道这件事,如果知道,它产生了什么作用?
在我看来,可以为静态源代码分析定义一个上下文,其中包括可以产生相对价值的规则。我知道这不是物理意义上的,因为源代码没有“能量”,但是我敢打赌,精湛的学术界已经做出了类似的努力。有谁知道这件事,如果知道,它产生了什么作用?
Answers:
已经有许多衡量代码复杂性的方法:
已经将这些与缺陷密度,维护工作和易于理解相关联。根据您要从分析中学到的知识,有些比其他的更有意义。我对物理科学中的熵的概念并不熟悉,但是我想知道,随着时间的推移,跟踪诸如我命名的度量和度量并将其与缺陷关联起来,是否与您所寻找的类似。
您可能还对Ivar Jacobson对软件熵和rot 的定义感兴趣。这些主题的总体思想是,随着时间的流逝,随着代码以及执行环境的变化,软件系统开始退化。重构被视为一种最小化熵或腐烂的方法,并且至少在我的经验中,我上面提到的度量和度量将指示系统或子系统中可能需要重构。
我认为您正在尝试在热力学熵和“复杂性”之间划清界限。事实是,熵是无序的一种度量,而不是复杂性。我不认为两者是等效的和可互换的。
与热力学熵最接近的类似物是Shannon熵,它测量随机变量中的无序量。该概念主要与消息中“信息”的数量有关。
在这方面,一段代码可以具有很多信息(高熵),但是复杂度却非常低。考虑一个简单地打印出很长的任意字符字符串的程序。它具有大量信息,但复杂度较低。
考虑熵的一种方法是“获取平均信息”,因此我认为最好回到建模信息的角度。我知道两种对信息进行数学建模的基本方法。(原谅我提供了维基百科参考,但恕我直言,它们还不错。)
Shannon Information,它查看符号集,符号集的概率分布,可以在符号集之间传递信息的代码以及这些代码的长度。香农信息理论阐述了代码效率,噪声,通过冗余进行错误检测和纠正等一般概念。表达信息的一种方法是说它是可以表示符号的最短二进制代码的长度。这是基于概率的,概率是某些观察者分配给符号或事件的数值。
Solomonoff(或Kolmogorov)信息。这是另一个解释。在这种表述中,符号或事件的信息内容由可以计算符号或事件的最短程序的长度表示。同样,这不是与观察者的分配概率有关,而是与可以执行程序的通用机器有关。因为每个通用机器都可以由通用图灵机模拟,所以从某种意义上讲,这意味着符号或事件的信息内容不是相对的,而是绝对的。
如果我可以自由地说出我认为这是我写过的一本书的日常用语,那仅意味着程序的复杂性就是程序的长度,而当诸如功能规范和语言之类的东西保持适当时,留有余地,例如注释和姓名长度。但是,这里存在一个问题-“ APL特快报”,其简洁程度等于不可理解的程度。
最好考虑一下(就像我在学习AI时一样)程序的功能规范包括一个心理模型,该模型不仅是真实的,而且是有效编码的,也就是说,冗余度很小,足以改变人们对需求的看法可以在没有太大内部不一致的危险的情况下完成此操作-即具有“错误”。然后编程的过程是一个信息通道,该通道将心智模型作为输入,其输出是有效的源代码。然后,当心智模型发生变化时,必须在编程过程中输入该增量,并在源代码中将其转换为相应的增量。该增量很容易测量。在应用该增量之前和应用该增量之后(完全解决所有错误),在源之间进行区分,并计算插入,删除和替换的代码块的数量。值越小,源代码语言就越能代表心理模型所代表的语言(就名词,动词和结构而言)。如果以某种方式在可能的功能更改的空间上对该度量进行平均,则这是源语言的熵的概念,且越少越好。这个有一个名词-领域特定语言(DSL)
很抱歉,如果参考文献不充分/个人,但我认为这一总体问题非常重要。
乔恩·贾格尔(Jon Jagger)和奥尔夫·莫达尔(Olve Maudal)对代码熵的看法略有不同,可以从他们2011年的Accu会议上看到代码熵和软件物理。
他们谈论代码的稳定性与将来的开发人员/维护人员是否可能更改该代码有关。
为了证明这一点,他们用大量代码片段进行了调查,结果非常有趣。
加上其他16个人。
总体趋势似乎是使代码更易于理解,更难于理解。
他们还研究了多年来对大型代码库所做的一些更改。
尽管幻灯片本身并不是会议的笔录,但仍有一些有趣的地方。
嗯,熵一词不仅出现在热力学和信息论中,而且还出现在数据压缩的现实世界中。在这种情况下,压缩器看到的熵等于其产生的位数。(请注意,我说的是“压缩器看到的熵”,因为认为熵取决于压缩器用来描述输入数据的模型。这就是为什么不同的压缩器生成大小不同的文件的原因:一个是对另一个的可利用结构。)
原则上,这可以很好地应用于源代码的复杂性:“只需”编写一个压缩器,该压缩器只能在完全符合标准的源代码上工作,并且像压缩编译器一样对它进行实际解析以生成相应的语法树。然后,它可以遍历此语法树,并在每个节点处确定在每个点上可能有哪些节点,并使用该知识对该节点进行编码。
因此,例如,如果该语言允许使用一个现有的标识符,或者使用括号括起来的东西或某个特定点的产品,那么压缩器将考虑可能的类型信息,对可能的现有标识符进行计数(例如,您有3个这样的标识符),并为两个可能的子表达式加2,从而提供5种可能性。因此,该节点将使用lb 5 = 2.32
位进行编码。在两个可能的子表达式的情况下,将需要更多的位来对其内容进行编码。
实际上,这确实可以非常准确地衡量代码的复杂性。但是,此措施仍然没有用!出于所有代码复杂度测量均无用的原因,它是无用的:它们失败确实在测得的代码复杂度(无论可能是多少)与代码解决的问题的复杂度之间建立了联系。您总是可以找到解决编程问题的极其复杂的解决方案,以LOC数量打动您的雇主,但是没有任何代码复杂性度量可以告诉您,只需花费一小部分精力就可以解决该任务。
代码的熵与数字π一样多。
代码维护和更改可能会引入熵(因为可能涉及状态更改)。
但是代码只是一个很大的数目。用二进制表示。