【问题标题】:How can i make this code more optimized - How can i replace the forloop.?我怎样才能使这段代码更优化 - 我怎样才能替换 for 循环。?
【发布时间】:2012-07-28 05:02:01
【问题描述】:

如果此代码 sn-p,我该如何提高性能。

bool OrSetFinalResult =true;
string OrSet = "(1&1)|0";
string[] AndSets = OrSet.Split('&');
foreach (string AndSet in AndSets)
{
    if (AndSet == "0")
    {
        // A single "false" statement makes the entire And statement FALSE
        OrSetFinalResult = false;
        break;
    }
}

有没有办法用LINQ 表达式删除 ForEach 循环?

【问题讨论】:

  • 不能用OrSet.Contains("0")吗?
  • 那么以OrSet = "1|0&1|0"为例,输出应该是什么?
  • 我错了还是拆分后你会有"(1"和"1)|0"字符串,你的if语句总是错误的?

标签: c# linq optimization


【解决方案1】:

听起来像:

if (AndSets.Contains("0"))
{
    OrSetFinalResult = false;
}

根本不需要 LINQ。当然,它仍然会在内部循环,但它仍然要简单得多。

编辑:如 cmets 中所述,您还可以使用:

OrSetFinalResult = OrSetFinalResult && !OrSet.Split('&').Contains("0");

【讨论】:

  • 你不能只做OrSetFinalResult = AndSets.Contains("0");吗?
  • @norlando:这是我的第一个答案(嗯,倒置),但不一定。假设OrSetFinalResult 已经为假,但其中没有任何“0”元素。我们不一定要将其设置为 true。
  • OrSetFinalResult = OrSetFinalResult && !OrSet.Split('&').Contains("0") 将@norlando 的方法与您对OrSetFinalResult 可能已经是错误的担忧相结合,在这种情况下跳过整个事情的额外好处。
  • 糟糕,我好像忘记在支票中添加 !。
  • 但是......这并没有太大的改进......只有一点点改进
【解决方案2】:

您没有包含OrSetFinalResult 的定义,所以我能想到的最快的是:

OrSetFinalResult = OrSetFinalResult && !OrSet.Split('&').Contains("0");

因为如果它已经是假的,这会跳过整个事情。

更一般地说,您可以对任何搜索做的最好的事情是:

  1. 如果集合是根据您要搜索的特征(在本例中是字符串本身)进行哈希处理,则 O(1)。
  2. 如果集合是根据您要搜索的特征进行排序的,那么 O(log n)。
  3. 如果集合没有排序,那么 O(n)。

有中间情况。例如。如果我想从一组仅在 X 坐标上排序的坐标中找到一个特定的 X-Y 坐标,那么它是 O(√n log √n),假设分布合理。

在这种情况下,我们有 O(n) 的情况。

将这些值放入HashSet<string> 将使这个搜索成为 O(1),但这样做本身就是一个 O(n) 操作(并且具有更高的常数效果)。因此,如果您要搜索多次,但如果您只搜索一次,这将是一种节省。

【讨论】:

  • OrSetFinalResult 是一个布尔变量,我已经对其进行了编辑,请参阅编辑。
  • 然后我将它的定义放在 OrSet 之后,并将其命名为 bool OrSetFinalResult = !OrSet.Split('&').Contains("0");。我所说的关于更普遍的搜索问题仍然适用。
  • 但是......这并没有太大的改进......只有一点点改进
  • 是的。由于给出的原因,O(n) 是你能做的最好的事情。你可以在你的代码中使用OrSet.Contains("0") 甚至OrSet.Contains('0') since it's one-char long, but I assume that the Split` 得到改进,这并不是真正的代码如何获得它的值。仍然是 O(n)。
【解决方案3】:

您可以在 Linq 中使用 Any 运算符。

string OrSet = "(1&1)|0";
string[] AndSets = OrSet.Split('&');
OrSetFinalResult = !AndSets.Any(x => x == "0");

【讨论】:

  • 但是......这并没有太大的改进......只有一点点改进
【解决方案4】:

在大多数情况下,用 LINQ 替换字符串解析与优化相反(假设您的意思是运行时优化)。

我猜线性分词器会快得多。也许我会做一个示例基准测试(如果我有时间的话)

【讨论】:

    【解决方案5】:
    string OrSet = "(1&1)|0";
    bool OrSetFinalResult = true;
        if (OrSet.Contains("0"))
        {
            // A single "false" statement makes the entire And statement FALSE
            OrSetFinalResult = false;
    
        }
    

    这会给你同样的结果。

    【讨论】:

    • 但是......这并没有太大的改进......只有一点点改进
    • 它消耗的内存比你维护的要少得多
    【解决方案6】:

    您可以在 linq 中使用 any 运算符,这会产生类似的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      • 2014-06-18
      • 1970-01-01
      • 2017-12-20
      相关资源
      最近更新 更多