-3

I have an IEnumerable object which has a field called Data. Data has values separated by ';'. I need to split this Data with ';' and assign this into another field in the same IEnumerable which is an array element. Eg:

IEnumerable<Object> = 
[{
    Data = "123;345",
    DataList = {}
},
{
     Data = "32424;87878",
    DataList = {}
}] 

and continues..

I need to split the Data in each row and assign to DataList in the same row. Could anyone provide with a lambda expression to do the same

Minu
  • 232
  • 4
  • 13
  • 4
    Why LINQ? That's something you'd do with String.Split() in a foreach loop. – 15ee8f99-57ff-4f92-890c-b56153 Sep 18 '17 at 15:51
  • Did you might want to use a *Linq Expression*? for the use in entity Framework or other Linq Provider? – Venson Sep 18 '17 at 15:51
  • Just for performance. – Minu Sep 18 '17 at 15:51
  • 4
    Linq is slower then a simple ForEach! not much but it is – Venson Sep 18 '17 at 15:52
  • 4
    `Just for performance` <= how so? Why would you think Linq is faster over the ForEach? – Igor Sep 18 '17 at 15:52
  • 4
    LINQ isn't faster by definition, it just hides the ugly loops in your code. And the Q is for "query", not for "side effect". – René Vogt Sep 18 '17 at 15:53
  • 2
    https://stackoverflow.com/questions/3156059/is-a-linq-statement-faster-than-a-foreach-loop – Venson Sep 18 '17 at 15:53
  • I was looking to convert it into lambda expression hoping it would be more better in performance. – Minu Sep 18 '17 at 15:54
  • 1
    If anything, it will probably be worse in performance... – DavidG Sep 18 '17 at 15:55
  • @Minu What led you to believe that calling a lambda expression from a loop would be faster than a loop? Do you think LINQ isn't looping? – 15ee8f99-57ff-4f92-890c-b56153 Sep 18 '17 at 15:55
  • As just pointed out it won't be. **If** you wanted to speed it up you could use the [parallel foreach extension](https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach(v=vs.110).aspx) instead. The assumption here is that it's slow because of the number of elements in your list and not related to your split code or something else in your loop. – Igor Sep 18 '17 at 15:56
  • @EdPlunkett I did not get your question. – Minu Sep 18 '17 at 15:56
  • @Igor Okay. I will try that. – Minu Sep 18 '17 at 15:57
  • I am sorry for my lack of knowledge. I am still a newbie in using LINQ and something made me believe that it is always better in performance. – Minu Sep 18 '17 at 15:57
  • @Minu It's a loop either way. What do you think LINQ is doing if not looping? You can't see the loop, but when you think about it, there must be a loop somewhere. *What* made you believe that LINQ improves performance? More importantly: What actual measured performance issue are you addressing here? Don't optimize until you have identified a performance problem that you need to fix. And of course don't optimize until you fully understand both the problem code, and the optimized code. Otherwise 3/4 of your "optimizations" will degrade performance of code that was fine before. – 15ee8f99-57ff-4f92-890c-b56153 Sep 18 '17 at 15:57
  • 1
    Relevant: https://ericlippert.com/2012/12/17/performance-rant/ – DavidG Sep 18 '17 at 16:01
  • Take a look at this article by Joe Duffy: [http://joeduffyblog.com/2010/09/06/the-premature-optimization-is-evil-myth/](http://joeduffyblog.com/2010/09/06/the-premature-optimization-is-evil-myth/). I would recommend reading the whole article, but the discussion on LINQ starts about half way through article. – TnTinMn Sep 18 '17 at 16:02

1 Answers1

4

Putting performance aside for a moment I'll start with the inline "elegant" (opinion based) solution for the question of a substitute for the traditional ForEach:

collection.ToList().ForEach(item => { item.DataList = item.Data.Split(';'); });

Now, looking at the ReferenceSource what actually stands behind ForEach this is a simple loop:

for(int i = 0 ; i < _size; i++) {
    /* O(1) code */
    action(_items[i]);
}

Note that this is not a linq solution. It uses lambda expressions but ForEach is not a function of linq

Now back to performance. There are two issues.

  1. The less significant one is that for each iteration of the internal loop there is another function call to the passed Action.
  2. The more significant one is that as described the object is an IEnumerable<T>. ForEach is a method of IList. Therefore there is a call to ToList() that creates a new collection at performs in O(n) which is not needed.

I'd just go with the simple straight forward solution of:

foreach(var item in collection)
{
    item.DataList = item.Data.Split(';');
}

As a general note about linq:

  1. Linq is for manipulations on collections and not really for updating the items enumerated. Here an update operation is needed so linq is not the best fitting solution.
  2. Performance - For in-memory collection linq will only improve performance when the deffered execution is relevant and the non-linq implementation is not lazy. When working with linq-to-X such as to some database it is a complete different world and very much depends on the specific linq provider. As a whole it can help you perform operations in a single DB query where otherwise, if not implemented in the database, will be in several queries.

Worth reading: Is a LINQ statement faster than a 'foreach' loop?

Community
  • 1
  • 1
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • I think I got confused between LINQ and Lambda. So if I get it right, making it a Lambda expression also does not improve performance right? It just makes the code more readable. Esp as in this case we need to convert to List first. Is my understanding correct? – Minu Sep 18 '17 at 16:21
  • @Minu - likely, many confuse the two at first. linq, when in method syntax is basically passing lambas to different functions. Notice that also then no performance improvement is for sure, most likely about the same from bellow – Gilad Green Sep 18 '17 at 16:23
  • @Minu - yes :) And I'd say especially because of the need to convert the collection to a list. – Gilad Green Sep 18 '17 at 16:23
  • Thank you everyone for all the inputs. Got a very big confusion cleared out. Thank you for your valuable time. – Minu Sep 18 '17 at 16:33