-3

Good Morning,

For such a simple loop (although the input object could have hundreds of items) would Linq be any faster or would the compiler just create the same basic loop out of the Linq statements?

Any ideas?

TIA

public static string ConcatWithDelimiter(object[] input, string prop, string delimiter)
{
    List<FDXCategory> categories = new List<FDXCategory>();

    var j = input.Select(i => i.ToString()).ToList();

    foreach (var VARIABLE in j)
    {
         var x = JsonConvert.DeserializeObject<FDXCategory>(VARIABLE);
         categories.Add(x);
    }

    switch (prop)
    {
       case "Id":
          return categories.Select(c => c.Id).Aggregate((a, b) => a + delimiter + b);

       case "Name":
          return categories.Select(c => c.Name).Aggregate((a, b) => a + delimiter + b);
     }
        
     return "Invalid Property Name";
}
GPGVM
  • 5,515
  • 10
  • 56
  • 97
  • LINQ is almost never faster than a well-coded alternative. It enables you to write more succinct code in most cases but there is generally overhead associated with a LINQ query so it's often a little bit slower. There's still basically a loop inside the query so you're just hiding it, not eliminating it. – jmcilhinney Aug 30 '23 at 11:34
  • 1
    [Which is faster?](https://ericlippert.com/2012/12/17/performance-rant/) Test it yourself. – DavidG Aug 30 '23 at 11:35
  • 4
    Using a StringBuilder instead of repeated concatenation would probably be quicker though... – Jon Skeet Aug 30 '23 at 11:35
  • If you want to make it more efficient, start by removing the `.ToList()`. Both LINQ and foreach work perfectly on the `IEnumerable` which `input.Select(i => i.ToString())` yields. `.ToList()` wastes memory and CPU cycles. – Olivier Jacot-Descombes Aug 30 '23 at 11:35
  • 1
    I'd also ask if you really need to be using `object` here. Using actual strings would prevent the need for boxing, and the LINQ/ToString stuff you have going on. – DavidG Aug 30 '23 at 11:39
  • 1
    There is also a handy [String.Join Method](https://learn.microsoft.com/en-us/dotnet/api/system.string.join) which is easier to use and is probably more efficient than LINQ's `Aggregate`. – Olivier Jacot-Descombes Aug 30 '23 at 11:46
  • And if inputs is just a list of Json string , you can simply get the part needed at deserialisation. Then yield those to a sting join. Btw, an MRE with a simple class, input values would have been nice. – Drag and Drop Aug 30 '23 at 11:49
  • @DavidG: I don't see any evidence that there's boxing here. There might be, but we can't tell without knowing the original type. – Jon Skeet Aug 30 '23 at 11:56
  • Here is a quick demo on how to do it without your tripple loop and bad string concatenation: https://dotnetfiddle.net/LNtiuS , Func will provide type and you wont be able to call a properties that dosent exist. Note that there is a versin using a sJsonPath that will act like your String propertyName, in the version 2. But `string Concat(string[] source, Func propertySelector, string delimiter) => string.Join(delimiter, source.Select(JsonConvert.DeserializeObject).Select(propertySelector));` should be enought – Drag and Drop Aug 30 '23 at 12:20
  • @JonSkeet Sure, I should have written "may prevent", at least I got the first half right! Though I would put money on there being some boxing going on. – DavidG Aug 30 '23 at 13:10
  • @DavidG: "Though I would put money on there being some boxing going on." Why? I see *zero* indications that there are value types involved. There may be, of course - but equally it could easily be multiple different domain model classes. – Jon Skeet Aug 30 '23 at 13:23

0 Answers0