代码之家  ›  专栏  ›  技术社区  ›  abatishchev Karl Johan

哪个接线员更快?:或&&

  •  4
  • abatishchev Karl Johan  · 技术社区  · 14 年前

    开发时ASP.NET应用程序我经常需要解析一个以字符串形式给出的布尔值,例如从一个查询字符串 ?visible=true

    我找到了两种实现解析的解决方案:

    bool Visible
    {
        get
        {
            bool b;
            return Boolean.TryParse(this.Request["visible"], out b) && b;
        }
    }
    

    bool Visible
    {
        get
        {
            bool b;
            return Boolean.TryParse(this.Request["visible"], out b) ? b : false;
        }
    }
    

    你认为哪种方式更可取?可能更快?

    顺便说一句,这不是一个微小的选择,我只是想知道

    6 回复  |  直到 13 年前
        1
  •  17
  •   Mikael Svenson    14 年前

    不要微优化,让它可读。

    bool visible;
    Boolean.TryParse(this.Request["visible"], out visible);
    return visible;
    

    因此,在我看来,它不仅可读性更好,而且跳过了 if 声明。另外两个有相等的操作码,只是在检查时切换了逻辑。

    [编辑-使用发布标志编译-较短的IL]

    如果您查看以下三种实现:

    public bool Visible1
    {
        get 
        {
            bool b;
            return Boolean.TryParse(HttpContext.Current.Request["visible"], out b) && b;
        }
    }
    
    public bool Visible2
    {
        get
        {
            bool b;
            return Boolean.TryParse(HttpContext.Current.Request["visible"], out b) ? b : false;
        }
    }
    
    public bool Visible3
    {
        get
        {
            bool b;
            Boolean.TryParse(HttpContext.Current.Request["visible"], out b);
            return b;
        }
    }
    

    将产生以下IL代码:

    .method public hidebysig specialname instance bool get_Visible1() cil managed
    {
        .maxstack 2
        .locals init (
        [0] bool b)
        L_0000: call class [System.Web]System.Web.HttpContext [System.Web]System.Web.HttpContext::get_Current()
        L_0005: callvirt instance class [System.Web]System.Web.HttpRequest [System.Web]System.Web.HttpContext::get_Request()
        L_000a: ldstr "visible"
        L_000f: callvirt instance string [System.Web]System.Web.HttpRequest::get_Item(string)
        L_0014: ldloca.s b
        L_0016: call bool [mscorlib]System.Boolean::TryParse(string, bool&)
        L_001b: brfalse.s L_001f
        L_001d: ldloc.0 
        L_001e: ret 
        L_001f: ldc.i4.0 
        L_0020: ret 
    }
    
    .method public hidebysig specialname instance bool get_Visible2() cil managed
    {
        .maxstack 2
        .locals init (
        [0] bool b)
        L_0000: call class [System.Web]System.Web.HttpContext [System.Web]System.Web.HttpContext::get_Current()
        L_0005: callvirt instance class [System.Web]System.Web.HttpRequest [System.Web]System.Web.HttpContext::get_Request()
        L_000a: ldstr "visible"
        L_000f: callvirt instance string [System.Web]System.Web.HttpRequest::get_Item(string)
        L_0014: ldloca.s b
        L_0016: call bool [mscorlib]System.Boolean::TryParse(string, bool&)
        L_001b: brtrue.s L_001f
        L_001d: ldc.i4.0 
        L_001e: ret 
        L_001f: ldloc.0 
        L_0020: ret 
    }
    
    .method public hidebysig specialname instance bool get_Visible3() cil managed
    {
        .maxstack 2
        .locals init (
        [0] bool b)
        L_0000: call class [System.Web]System.Web.HttpContext [System.Web]System.Web.HttpContext::get_Current()
        L_0005: callvirt instance class [System.Web]System.Web.HttpRequest [System.Web]System.Web.HttpContext::get_Request()
        L_000a: ldstr "visible"
        L_000f: callvirt instance string [System.Web]System.Web.HttpRequest::get_Item(string)
        L_0014: ldloca.s b
        L_0016: call bool [mscorlib]System.Boolean::TryParse(string, bool&)
        L_001b: pop 
        L_001c: ldloc.0 
        L_001d: ret 
    }
    
        2
  •  5
  •   MarkR    14 年前

    我认为他们两个可能在功能上都是错误的(也许我不明白你想做什么),但即使他们是正确的,你也不在乎哪个更快。

        3
  •  3
  •   Justin Ethier    14 年前

    第一个更好一点,因为它使用更少的代码,所以我同意。

    我怀疑这两者之间的速度差异有多大,但是如果你真的在意的话,你应该对它们进行分析——每一个都运行一百万次左右,并记录运行时间。

        4
  •  3
  •   Simon Steele    14 年前

    bool Visible
    {
        get
        {
            bool b;
            Boolean.TryParse(this.Request["visible"], out b)
            return b;
        }
    }
    

    b 将设置为 default(bool) (false)如果TryParse失败。

    以及 b 必须由TryParse设置,因为它是 out 变量。

        5
  •  2
  •   Coding Flow    14 年前

    与页面生命周期的成本相比,两者之间的速度差将是无穷小的。两者的主要问题是可读性不强。你为什么不简单地做一下:

    return Request["visible"] == "true";
    

    它达到了同样的目的,它是完全清楚的。我看不出你所做的有什么价值,只是令人困惑。

        6
  •  0
  •   Guffa    14 年前

    在这种情况下,它不会有任何重大区别。解析字符串花费的时间太长了,运算符之间的细微差别无关紧要。

    在这种情况下,它会产生任何不同,您应该分析代码,以知道哪一个实际上更快。真正的性能不仅取决于单个操作符,还取决于在代码中该点之前和之后执行的操作。

    一个有根据的猜测是 &&