C# 哪个操作员更快:?:或&&;

C# 哪个操作员更快:?:或&&;,c#,asp.net,.net,boolean,conditional-operator,C#,Asp.net,.net,Boolean,Conditional Operator,在开发ASP.NET应用程序时,我经常需要解析以字符串形式给出的布尔值,例如,从查询字符串中,如?visible=true 我找到了两种实现解析的解决方案: bool Visible { get { bool b; return Boolean.TryParse(this.Request["visible"], out b) && b; } } 或 你认为哪种方式更可取?也许更快 另外,这不是一个微选择,我只是想知道 p.

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

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

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

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


另外,这不是一个微选择,我只是想知道


p.p.S.我对IL不太熟悉,所以决定在这里问一下

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


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

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


你真的,真的不在乎。

不要微优化,让它可读

我认为这更具可读性:

bool visible;
Boolean.TryParse(this.Request["visible"], out visible);
return visible;
可读的变量名通常有帮助;)与其他两种实现相比,这种实现实际上产生的操作代码更少,我假设它将以更少的周期执行,比您的两种尝试都要快

因此,在imo中,它不仅可读性更强,而且速度更快,因为它跳过了
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 
}

事实上,另一种方式是

bool Visible
{
    get
    {
        bool b;
        Boolean.TryParse(this.Request["visible"], out b)
        return b;
    }
}
因为
b
将在TryParse失败时设置为
默认值(bool)
(false)

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


不要对代码进行微优化,使其可读

在这种情况下,根本不会产生任何显著差异。解析字符串的时间要长得多,因此运算符之间的微小差异无关紧要

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


一个有根据的猜测是
&&
操作符的速度要快一些。因为没有条件跳转,所以与现代处理器相比,它更适合于连续操作的并行处理。

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

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

它达到了同样的目的,而且非常清晰。我看不出你所做的有任何价值,这只是让人困惑。

或者看他们产生了什么。无论哪种情况,这都是微观优化,无所谓。按照你的建议,使用干净的代码。我只是想知道,可能是在IL上level@abatishchev:那么看看IL。它不是一个微型opt,我只是想know@abatishchev:用正确的IL代码编辑了我的答案。上一版本是调试版本,未进行优化。事实证明,我提出的代码也更快。主要是因为跳过了if语句。
String.Equals(请求[“可见”]、Boolean.TrueString、StringComparison、OrdinalIgnoreCase)
可能更正确的说法是“True”。TryParse实际做的就是Equals(value、StringComparison.OrdinalIgnoreCase)。然后为“False”。然后它会修剪空白,并在必要时再次检查两个字符串。@Yves:我不熟悉IL,所以决定在这里询问
return Request["visible"] == "true";