How to use a delegate in this scenario?

One development friend of mine tells me that loops are much faster using delegates, and I would like to compare them, but I am having problems connecting dots to how this works.

Consider the following balance calculator. This basically takes a list of accounts and adds an initial value (initial balance) if it exists for the total value of loans, if it exists, and subtracts the total value of debits for each account:

    private static IDictionary<string, decimal> CalculateBalances(
        IDictionary<string, decimal> initialValue, 
        IDictionary<string, decimal> credits, 
        IDictionary<string, decimal> debits)
    {
        var r = new Dictionary<string, decimal>();

        foreach (var key in initialValue.Select(k => k.Key)
            .Concat(credits.Select(k => k.Key))
            .Concat(debits.Select(k => k.Key))
            .Distinct())
        {
            r.Add(key,
                (initialValue.ContainsKey(key) ? initialValue[key] : 0M)
                + (credits.ContainsKey(key) ? credits[key] : 0M)
                - (debits.ContainsKey(key) ? debits[key] : 0M)
                );
        }

        return r;
    }

This is pretty efficient with small to medium account lists, but will using delegates be faster? And frankly, delegate logic seems to work at right angles to my thought processes, because I scratch my head, how to even write this.

- ?

+3
3

, - ForEach List<T>. : .

:

initialValue.Select(k => k.Key)
            .Concat(credits.Select(k => k.Key))
            .Concat(debits.Select(k => k.Key))
            .Distinct()
            .ToList()
            .ForEach(var => r.Add(key,
                (initialValue.ContainsKey(key) ? initialValue[key] : 0M)
                + (credits.ContainsKey(key) ? credits[key] : 0M)
                - (debits.ContainsKey(key) ? debits[key] : 0M)
                ));

, . . , . , , .

+5

- ?

! , . , , , .

, , List.ForEach , .

, LINQ :

return initialValue
       .Concat(credits)
       .Concat(debits.Select(kvp => new KeyValuePair<string, decimal>(kvp.Key, -kvp.Value)))
       .GroupBy(kvp => kvp.Key, kvp => kvp.Value)
       .ToDictionary(group => group.Key, group => group.Sum());

.

+2

foreach , Dictionary.Add. , , .

, , ?

private static decimal GetOrZero(this IDictionary<string,decimal> dict, string key)
{
    decimal value = 0;
    dict.TryGetValue(key, out value);
    return value;
}

private static IDictionary<string, decimal> CalculateBalances(
    IDictionary<string, decimal> initialValue, 
    IDictionary<string, decimal> credits, 
    IDictionary<string, decimal> debits)
{   
    var r = new Dictionary<string, decimal>();
    var accounts = initialValue.Keys.Union(debits.Keys).Union(credits.Keys);

    foreach (var accounts in accounts)
    {
        r.Add(initialValue.GetOrZero(key) + credits.GetOrZero(key) - debits.GetOrZero(key));
    }

    return r;
}
0
source

All Articles