哪个运算符更快:?:或&&

aba*_*hev 4 .net c# asp.net boolean conditional-operator

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

我发现了两种解决方案来实现解析:

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

要么

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

您如何看待首选哪种方式?可能更快?

PS这不是微观选择,我只是想知道

PPS我不熟悉IL所以决定在这里问

Mik*_*son 17

不要微观优化,让它可读.

我认为这更具可读性:

bool visible;
Boolean.TryParse(this.Request["visible"], out visible);
return visible;
Run Code Online (Sandbox Code Playgroud)

可读的变量名通常有帮助;)与其他两个相比,这个实现实际上产生更少的操作码,我认为它将以更少的周期执行,比你的两次尝试都要快.

因此,它不仅更具可读性,而且更快,因为它会跳过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;
    }
}
Run Code Online (Sandbox Code Playgroud)

将产生以下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 
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*rkR 5

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

你真的,真的不在乎.