哪个运营商更快:?:或&&

时间:2010-08-20 13:42:56

标签: 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;
    }
}

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

您认为哪种方式更受青睐?可能更快?

P.S。这不是微观选择,我只是想知道

P.P.S。我不熟悉IL所以决定在这里问一下

6 个答案:

答案 0 :(得分:17)

不要微观优化,使其可读。

我认为这更具可读性:

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 
}

答案 1 :(得分:5)

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

你真的,真的不在乎。

答案 2 :(得分:3)

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

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

答案 3 :(得分:3)

实际上,另一种方式是

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

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

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

不进行微观优化,编码使其可读。

答案 4 :(得分:2)

与页面生命周期的成本相比,它们之间的速度差异将是无穷小。它们的主要问题是它们不是很易读。为什么不简单地执行以下操作:

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

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

答案 5 :(得分:0)

在这种情况下,它根本不会产生任何重大差异。解析字符串需要花费更长的时间,以至于运算符之间的微小差别无关紧要。

如果它会产生任何差异,您应该分析代码以了解哪个实际上更快。真正的性能不仅取决于单个运算符,还取决于代码中该点之前和之后的操作类型。

一个有根据的猜测是&&运算符有点快。因为没有条件跳转,所以现代处理器的连续操作的并行处理会更好。