Following my previous question关于超长函数背后的原理,我想提出一个关于我正在研究的piece of code的具体问题。这是一个来自Linux内核的函数,它相当长(412行)和复杂( MCC index为133)。基本上,它是一个很长的嵌套switch语句
坦率地说,我想不出任何方法来改善这种混乱。调度表看起来既庞大又低效,任何子例程调用都需要难以想象的参数数量才能覆盖足够大的代码段。
你有没有想过用一种更具可读性的方式重写这个函数,而不会降低效率?如果不是,代码对您来说是否可读?
不用说,在我的研究中出现的任何答案都将得到充分的信任-无论是在这里还是在提交的论文中。
Link to the function in an online source browser
发布于 2009-07-15 21:40:57
太可怕了,IMHO。显而易见的第一个修复方法是使开关中的每个case都调用一个函数。在任何人开始抱怨效率之前,让我先说一个词--“内联”。
编辑:这段代码会不会是Linux FPU仿真器的一部分?如果是这样的话,这是一个非常古老的代码,是为了让linux在英特尔芯片上工作,比如没有FPU的386。如果是这样的话,除了历史学家,这可能不是一个适合学者的研究!
发布于 2009-07-15 21:28:44
我不认为这个函数是乱七八糟的。我以前写过这么一团糟的东西。
该函数是从微处理器制造商转换成表的代码。这是非常低级的东西,为特定的中断或错误原因复制适当的硬件寄存器。在这类代码中,您通常不能接触硬件未填充的寄存器-这可能会导致总线错误。这可以防止使用更通用的代码(如复制所有寄存器)。
我确实看到了一些重复的代码。然而,在这个级别(在中断级别操作),速度更重要。除非我知道提取的方法是内联的,否则我不会在公共代码上使用提取方法。
顺便说一句,当你在那里(内核)的时候,一定要捕捉到这段代码的变化历史。我怀疑你会发现这里没有太多的变化,因为它与硬件绑定在一起。这类代码随时间的变化的性质将与大多数用户模式代码所经历的变化的性质完全不同。
例如,当实施新的整合IO芯片时,这类事情将会发生变化。在这种情况下,更改很可能是复制和粘贴并更改新副本,而不是修改现有代码以适应更改的寄存器。
发布于 2009-07-15 21:35:43
我将从定义各个类的常量开始。在这段代码中,切换是为了什么是一个谜;如果切换是针对命名常量的,那么我就有了一个起点。
更新:您可以删除大约70行案例返回MAJOR_0C_EXCP的行;只需让它们一直保留到例程的结尾即可。因为这是内核代码,所以我会提到它可能会有一些性能问题,特别是在case顺序已经优化的情况下,但它至少会减少您需要处理的代码量。
https://stackoverflow.com/questions/1134174
复制相似问题