Following my previous question关于极长函数背后的基本原理,我想提出一个关于piece of code我正在研究我的研究的具体问题。它是来自Linux内核的一个函数,它很长(412行)和复杂(133 MCC index)。基本上,它是一个长而嵌套的switch语句
坦率地说,我想不出任何改善这种混乱的方法。调度表似乎既庞大又低效,任何子程序调用都需要一个不可思议的参数,以便覆盖足够大的代码段。您是否认为可以以更易读的方式重写此功能,而不会降低效率?如果没有,代码看起来是否可读?
毋庸置疑,我的研究中出现的任何答案都会得到充分的信任 - 无论是在这里还是在提交的论文中。
答案 0 :(得分:4)
我认为这个功能并不是一团糟。我以前不得不写这么一团糟。
该功能是从微处理器制造商转换为表格的代码。它是非常低级的东西,为特定的中断或错误原因复制适当的硬件寄存器。在这种代码中,您经常无法触及未被硬件填充的寄存器 - 这可能导致总线错误。这可以防止使用更通用的代码(比如复制所有寄存器)。
我确实看到了似乎有些代码重复。但是,在此级别(在中断级别操作),速度更重要。我不会在公共代码上使用Extract Method,除非我知道提取的方法将被内联。
这种情况会发生变化,例如,当实施新的整合IO芯片时。在这种情况下,更改可能是复制和粘贴并更改新副本,而不是修改现有代码以适应更改的寄存器。
答案 1 :(得分:1)
我首先要为各种类定义常量。冷静地谈到这个代码,切换的目的是个谜。如果切换是针对命名常量的,我会有一个起点。
更新:您可以删除大约70行,其中案例返回MAJOR_0C_EXCP;简单地让它们落到例行程序的末尾。由于这是内核代码,我会提到可能存在一些性能问题,特别是如果案例顺序已经优化,但它至少会减少您需要处理的代码量。
答案 2 :(得分:1)
这里有一种规律性,我怀疑对于一个领域专家来说,这实际上感觉非常连贯。
同样具有近距离接近的变化允许立即进行目视检查。
我认为不需要重构此代码。
答案 3 :(得分:1)
非常可怕,恕我直言。明显的一阶修复是让交换机中的每个案例都调用一个函数。在任何人开始抱怨效率之前,我只想说一句话 - “内联”。
编辑:这个代码是否是Linux FPU模拟器的一部分?如果是这样,这是一个非常古老的代码,这是一个黑客,让Linux在像没有FPU的386等英特尔芯片上工作。如果是的话,除了历史学家之外,它可能不适合学术界的研究!
答案 4 :(得分:0)
我对内核或者重新分解它们的工作方式知之甚少。
我想到的主要事情是采用switch语句并将每个子步骤分解为一个单独的函数,其名称描述了该部分正在执行的操作。基本上,更具描述性的名称。
但是,我认为这不再优化功能。它只是打破了它可能有用的较小功能......我不知道。
那是我2美分。