当前位置: 首页 > 编程语言 > C#

在C#中应用DeMorgan定理来手动优化条件语句中的布尔表达式(例如条件)是否有用分享

时间:2023-04-11 00:06:43 C#

C#LearningTutorial:IsitusefultoapplyDeMorgan'stheoreminC#tomanuallyoptimizeBooleanexpressionsinconditionalstatements(eg.condition)会很有用回到我大部分工作在C和C++中的日子,当然我会手动应用deMorgan定理来优化任何非平凡的布尔表达式。在C#中执行此操作是否有用,或者优化器是否不需要这样做?有了这么快的处理器,几乎不可能重新排列布尔表达式来真正提高速度。C#编译器非常聪明,它也优化了它。针对可读性和清晰度进行了优化!您的首要目标应该是优化这些语句,使它们易于开发人员理解并易于维护。DeMorgan定理可能是一个有用的工具。JIT中的优化,以其目前的形式,并没有(根据我所读到的)为您优化。如果你需要优化它,你仍然需要考虑到这一点。也就是说,这是一个相当小的微优化。通常,我更喜欢以更具表现力的形式编写“重要的布尔表达式”,以便更容易理解。对我来说,这比通过应用deMorgan定理获得的任何非常小的优化更有价值。我相信这个问题的正确答案是编译器不会(通常)优化布尔值评估,仅仅是由于逻辑短路,例如:if(GetFlagA()||GetFlagB()){...dosomething}如果GetFlagA被调用depends,则可以修改GetFlagB,那么评估的顺序非常重要(当然这是非常糟糕的代码实践,但这是另一个主题的主题。)这里的问题是逻辑短路,如果GetFlagA运行并返回true,GetFlagB将永远不会运行,如此处所示,GetFlagB的结果对于语句的评估无关紧要。一个|乙|=F|女|FF|吨|TT|女|无论B的返回值如何,都为真。T|T|无论B的返回值如何,都是如此。总而言之,询问您是否可以使用Demorgan或其他任何东西进行优化,就像计算机科学和软件工程的其余部分一样。“这取决于。”如果您使用的是非功能性评估,则可能会进行优化。老实说,你在谈论一个疯狂平台上的一些操作,你最好把时间花在写文档上。我希望这有帮助。唯一一次你应该重新排列,布尔代数或demoorgan是当逻辑太复杂而无法以另一种方式进行时。如果不是太复杂,请保持可读性。有一个简化逻辑的例子。有时当逻辑很棘手时,我需要创建一个卡诺图来将逻辑简化为我什至可以写下来的东西。通常,使用K-Map可以帮助您提供一种更简洁的逻辑表达方式。结果可能有意义也可能没有意义,但它是等价的。而且我还要说,DeMorgan本身并不是一种产生影响的优化,如果超过一半的项是负数(NOT),最多你会获得性能去除一些NOT,这是一个每个CPU指令.在最坏的情况下,您可以添加任意数量的NOT,如果您不应该使用DeMorgan,您最终会得到比原来更多的NOT。如果您正在优化逻辑,请使用一些布尔代数或我个人最喜欢的K-Maps来减少项数(如果可能)。不要只移动布尔运算符,这很愚蠢。我猜编译器已经这样做了。可以通过Reflector进行测试,查看编译后的IL。优化可读性和可维护性。问问自己一年后是否会理解一个聪明的优化,如果你认为是这样,代码可以使用一些注释使代码自文档化。由于布尔表达式求值使用快捷方式语义,您可以将成本较低的子表达式移到前面:if(CountAllFilesOnDrive('C:')>7&&useFileScan){...}在重新求值表达式时运行昂贵的调用中。如果useFileScan为假,useFileScan语句将跳过文件检查:if(useFileScan&&CountAllFilesOnDrive('C:')>7){...}DeMorgan可能会帮助您将“提前退出”移到前面,从而获得更好的平均水平表现。请注意,由于保证从左到右的评估,优化器没有太多修改表达式的自由。考虑可读性和维护性。如果您有一组相当复杂的难以阅读的布尔表达式,那么DeMorgan定理可能是将表达式简化为更易读/可维护的东西的好方法,但这仍然有效/与原来的不一致是一致的。另一方面,如果更简洁的表达更易于阅读且表达能力较差,而逻辑等价物则更难理解,请保持原样。在几乎所有我能想到的实际案例中,布尔运算符的排列对整体性能没有明显影响。如果你的程序等待数据库、网络等,那么它所花费的时间将远远超过那些微小的操作。如果您正在编写一个真正有所作为的程序,最好跳过C#并改用C++。在存在短路评估的情况下,DeMorgan本身可能完全无关紧要。返回!(exp1||exp2);返回!exp1&&!exp2;得到编译if(exp1)return!(true);否则返回!(exp2);如果(!(!exp1))返回假;否则返回!(exp2);如果不取消和不断折叠,这些是相同的。更重要的情况是评估顺序;在可能引发短路的表达前放置吱吱声。编译器无法为您优化它,因为很难检测到诸如副作用之类的语义问题,或者如果以下表达式基于前一个表达式做出假设:returnvalidState()&&checkAssumuingValidState();我同意可读性和可维护性是当今优化布尔表达式时最重要的一般性陈述。因此,德摩根定理在一般情况下是非常有用的。这条规则有一个例外。如果布尔表达式改变德摩根定理来优化表达式,可能更难维护。考虑一个具有多个输入的表达式,这些输入已被优化为仅显示某些布尔条件。对所需布尔逻辑的一次更改可能会迫使某人再次列出所有可能的布尔组合,并重新优化。如果表达式以未优化的形式保留,则完成更改所需的步骤会更少。从轶事的角度来看,我想知道对团队进行德摩根定理和卡诺图等方面的教育是否会减少不必要/低效的布尔表达式。也许如果有人对这些方法有很好的理解,他/她将倾向于生成更好的表达式。例如,我最近在维护的软件代码中遇到了这个布尔表达式:if({booleanvariable}!=true&&false)TheC#optimizercan'treallydomuch,giventheshort-circuitingrulesforlogicalexpressionevaluation。所以应用DeMorgan定律不会有太大作用,除非它允许您看到其他有用的重构(当然它可以帮助您的代码更清晰)。但在某些情况下,您可以通过其他类型的表达式优化来提高性能。例如,这些条件应该交换if(costly_boolean_function()&&cheap_often_false_boolean_function())SQL查询优化器当然会这样做,因为SQL不会短路。查询优化器将积极地重新排列连接WHERE子句谓词(以c1ANDc2AND...cn的形式),以便将最便宜的条件放在第一位,因为它们可以评估为false而不需要评估更昂贵的条件。首先处理可维护性和高级优化。然后处理低级优化。德摩根定律可用于将其简化为范式,例如析取范式(DNF)或合取范式(CNF)。基本上这意味着它也是DNF:(aandbandc)OR(eandfandg)...orCNF:(aorborc)AND(eorforg)....你可以把不要投入最低水平。我同意之前的海报,您应该针对可读性和理解性进行优化。对于我们所有非CS专业的学生:关于德摩根定律的维基百科:德摩根定律是通过否定将逻辑运算符“和”和“或”相关联的规则,即:NOT(PORQ)=(NOTP)AND(NOTQ)NOT(PandQ)=(NOTP)OR(notQ)以上是C#学习教程:在C#中应用德摩根定理手动优化条件语句(如condition)中的布尔表达式是否所有有用的内容分享,如果对大家有用,需要了解更多C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: