-4

Can anyone assist on below WPF GUI how to convert to Linq due to low performance:

foreach (Grid b in main_grid.Children)
{
    foreach (Control s in b.Children)
    {
        if (s.GetType() == typeof(Button))
        {
            if (s.Tag.ToString() == message)
            {
                if (status == "OIRS_INUSE")
                {
                    s.Background = Brushes.Orange;
                }
                else
                {
                    s.Background = defaultBackground;
                }
            }
        }
    }
}
Pac0
  • 21,465
  • 8
  • 65
  • 74
  • 4
    "How to convert to LINQ due to low performance"? Why do you think LINQ would yield better performance? LINQ still has to do a `foreach`. – ProgrammingLlama Dec 17 '18 at 01:33
  • 1
    What have you tried so far? – Marcel Dec 17 '18 at 01:35
  • Linq will not help your perfomance – T.S. Dec 17 '18 at 02:01
  • `s.GetType() == typeof(Button)` can be just `s is Button` – Dmitry Dec 17 '18 at 12:28
  • I'd like to answer this question. I've more optimizations. Please vote to reopen. – Dmitry Dec 17 '18 at 13:11
  • While I agree LINQ or no LINQ is not the issue here, at least OP has formulated its underlying issue (performance). – Pac0 Dec 17 '18 at 16:52
  • @LohZhiCheng : I'd suggest that you give more details about your performance issues in your question. Some numbers (size of lists, time taken, memory used...) are relevant to such question, along with your objective you would consider as acceptable. – Pac0 Dec 17 '18 at 16:55

1 Answers1

2

First, you are asking the wrong question. Linq doesn't help.

One way to speed up this loop is to reduce the workload of its bottleneck:

foreach (Grid b in main_grid.Children)
{
    foreach (Control s in b.Children)
    {
        if (s.SomeEnumValue == SomeEnum.Value)
        {
            s.Background = Brushes.Orange;
        }
        else
        {
            s.Background = defaultBackground;
        }
    }
}

First comparison if (s.GetType() == typeof(Button)) is costly:

for 100 million calls:

typeof(Test): 2756ms
TestType (field): 1175ms
test.GetType(): 3734ms

you'll have more than 5 times slower than a simple field comparison.

Second comparison if (s.Tag.ToString() == message) and third comparison status == "OIRS_INUSE" are costly

Moreover, the second comparison contains a ToString method which has its own cost.

So get rid of all these expensive comparisons and replace them with a simple field comparison such as an enum which is cheap.

Bizhan
  • 16,157
  • 9
  • 63
  • 101
  • Does `Control` have a property called `SomeEnumValue`? – mjwills Dec 17 '18 at 02:15
  • Could LINQ's `OfType` be of use? – mjwills Dec 17 '18 at 02:16
  • 1
    Why do you think `var` avoids a cast? Or that casting is expensive? – D Stanley Dec 17 '18 at 02:38
  • @DStanley thanks to your comment I found out `foreach (ExplicitType item in collection)` isn't expensive at all. I removed the last part of my answer. – Bizhan Dec 17 '18 at 08:29
  • @mjwills I'm suggesting OP to use a better comparison rather than parse and compare strings, so `SomeEnumValue` could be anything such as Tag or a custom property. I also removed the part about avoiding casting (look at my comment above) so `OfType` could be used but it wouldn't speed it up because it would still be applied to each element separately, just like inside of a loop – Bizhan Dec 17 '18 at 08:32
  • @mjwills I just tested a quick sample with `OfType` and I found out it's about twice as slow as `(s.GetType() == typeof(type))` I don't know why! – Bizhan Dec 17 '18 at 08:42