0

I have a Dictionary<String, Object> with some data in it.

I want to loop through each element, I know I can use foreach for that. But I little bit concerned about the performance and the memory usage for it.

But here's the thing, we know that for (;;) is faster and use less RAM ( if I remember correctly ) than foreach () since it doesn't create new instance for each element.

But we can't use for (;;) directly to iterate through it, so we need LINQ's ElementAt() or something similar for it.

So which is more efficient, is using foreach () more efficient

private Dictionary <String, Object> items;
foreach (var entry in items)
{
  // do something with entry
}

or using for (;;) combined with LINQ is more efficient

private Dictionary <String, Object> items;
for (var c = 0; c < items.Count; c++)
{
  // do something with items.ElementAt(c)
}

or for (;;) combined with LINQ is the same as foreach () because items.ElementAt() may also create instance ?

EDIT : If there's discussion discussing about it and maybe has the answer, feel free to mark this as duplicate, but let me know the reference.

deanrihpee
  • 178
  • 2
  • 11
  • 1
    Do you have a performance problem? – TheGeneral Jan 31 '19 at 09:57
  • 1
    You didn't show any LINQ code. `ElementAt()` isn't part of LINQ. The second example is contrived and thus, meaningless for comparison. What are you trying to do? Dictionaries don't have positions, they have keys and values and expose an `IEnumerable>` interface – Panagiotis Kanavos Jan 31 '19 at 09:59
  • 4
    Obligatory [racing horses/performance rant](https://ericlippert.com/2012/12/17/performance-rant/) link. – Wai Ha Lee Jan 31 '19 at 09:59
  • @MichaelRandall currently not much, because my data set is fairly on low count, but I'll use this approach not for normal App, I'll use this on some Game Engine, Unity, MonoGame, so what I notice is the loading time is a bit slow, but I doubt that is come from the Dictionary loading tho, but still, since I'm almost use Dictionary throughout the project and do much Adding and Removing element – deanrihpee Jan 31 '19 at 10:01
  • 1
    `ElementAt()` is part of `Enumerable` and performs N iterations to find an element. It's the first snippet performed N times. When the target type implements `IList` the way arrays and lists do, it simply uses `[]` to return an item. Otherwise it has to loop N times – Panagiotis Kanavos Jan 31 '19 at 10:02
  • "// do something with entry" what exactly does that mean? do you want to manipulate the items ? or simply extract data – Mong Zhu Jan 31 '19 at 10:03
  • I've closed this as a dupe because this question contains no Linq so is really asking the same question. – DavidG Jan 31 '19 at 10:04
  • @WaiHaLee well, I apologize but I still curious because I'm not really good at benchmarking and my experience is fairly shallow – deanrihpee Jan 31 '19 at 10:04
  • @MongZhu sorry, main focus was modifying it's value – deanrihpee Jan 31 '19 at 10:05
  • 2
    @deanrihpee curious about *what*? The two snippets aren't equivalent. Calling `ElementAt()` doesn't access the Nth item, there's no order in dictionaries. It *itereates* N times and returns the last item it encounters. Instead of N iterations, the second snippet performs N!. For 100 items, that's 5050 iterations – Panagiotis Kanavos Jan 31 '19 at 10:05
  • modifying is not as easy as it seems when using a loop. Have you tried it? In a foreach it will tell you that the `Value` property is readonly – Mong Zhu Jan 31 '19 at 10:07
  • [similar](http://codebetter.com/patricksmacchia/2008/11/19/an-easy-and-efficient-way-to-improve-net-code-performances/) article here – Gowtham Alan Jan 31 '19 at 10:07
  • @PanagiotisKanavos, "ElementAt isn't part of LINQ", really? – vc 74 Jan 31 '19 at 10:08
  • @PanagiotisKanavos so you say that using `ElementAt()` inside the `for (;;)` is actually do more 'action' than just using `foreach ()` ? – deanrihpee Jan 31 '19 at 10:08
  • when using the `[ ]` operator to access the elements you would endup with close to O(1). Like described in [this post](https://stackoverflow.com/questions/9057715/access-times-for-dictionary-hashset) I guess looping is always worse than that – Mong Zhu Jan 31 '19 at 10:09
  • @vc74 While it's in the `System.Linq` namespace, I don't think calling it Linq is particularly useful. – DavidG Jan 31 '19 at 10:09
  • @PanagiotisKanavos yes I'm not focus on the order, so it's taking more 'process' than usual `foreach ()` ? curious about which the method / logic is rather more quick, so now I know better, since you pointed out that `ElementAt` is iterate more(am i correct?) rather than quickly get the item, because on the other discussion someone pointed out that use `for (;;)` instead of `foreach ()` because it's faster (although it's List<> and array, not `Dictionary`) so I'm curious about the same scenario but with `Dictionary` – deanrihpee Jan 31 '19 at 10:14
  • @deanrihpee it's not the same scenario at all. Dictionaries don't have positions, which is why they don't have an order. They have *keys*. A meaningful comparison would be to iterate over the `.Keys` array and try to access items by their key. As for benchmarking, use [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet) and compare the two examples. – Panagiotis Kanavos Jan 31 '19 at 10:16
  • 1
    @MongZhu ah yes, on that case it's like `items[entry.Key] = newValue;` so the way I collect the `Key` is either from `foreach ()` or `ElementAt` – deanrihpee Jan 31 '19 at 10:18
  • @PanagiotisKanavos yes I aware Dictionary doesn't have position, but this is when the Dictionary is altered / modified without the Input key, do you mean ` foreach (var entry in items.Keys) { items[entry] = new Value(); } ` – deanrihpee Jan 31 '19 at 10:22
  • @PanagiotisKanavos and what about for (c;;c++) items[items.ElementAt(c).Key] = new Value(); ? or is it still bad since it iterate more ? – deanrihpee Jan 31 '19 at 10:23
  • 1
    @deanrihpee - Where did you get the idea from that `foreach` is slower or "costs more RAM"? Even if it does, is it *significant*? -- It's great to experiment, but then you need to actually do benchmarking very carefully. Usually, you don't switch to obscure ways to do stuff, when there are standard ways to do it. Only if you have real prove of a bottleneck (see the already linked "performance rant", it's really *really* good advice). -- so either `foreach` on the whole dictionary, or `foreach (var key in dictionary) { /* do something with dictionary[key] */ }`. – Corak Jan 31 '19 at 10:33
  • @Corak on `slower` I certain that someone discussing that on `foreach` is on the IL create new variable for the data when compiled, on more ram, I forgot, but something related to it, I see thanks for the insight – deanrihpee Jan 31 '19 at 10:39
  • @deanrihpee In addition to readability, there are other benefits you'll get with `foreach` (automatic disposal of the enumerator for instance) – vc 74 Jan 31 '19 at 11:59
  • https://stackoverflow.com/questions/141088/what-is-the-best-way-to-iterate-over-a-dictionary – Corak Feb 01 '19 at 05:56

0 Answers0