https://bugzilla.novell.com/show_bug.cgi?id=328036#c8


Michi Henning <[EMAIL PROTECTED]> changed:

           What    |Removed                                         |Added
----------------------------------------------------------------------------
                 CC|                                                |[EMAIL 
PROTECTED]




--- Comment #8 from Michi Henning <[EMAIL PROTECTED]>  2007-09-25 16:48:43 MST 
---
(In reply to comment #7 from Robert Jordan)
> I really thought about optimizing this, but I looked like a seldom hit
> corner case to me, because in many cases Key/ValueCollection.CopyTo will
> be called instead of the (hidden) ICollection.CopyTo.

I think the optimization might be worthwhile. For me, this issue arose in the
context of having existing code that uses sequence that are derived from
CollectionBase, and dictionaries that are derived from DictionaryBase. (This is
with Ice--see http://www.zeroc.com)

With C# 2.0, we decided to provide an updated collection mapping that uses
strongly-type containers, such as List<T> and Dictionary<KT, VT>.

Now we need to support both the old and the new mappings, and one of the
requirements is that we need deep equality semantics. Rather than generating
(or requiring the user to write) a separate comparison method for each
strongly-typed collection, I wanted to provide a comparison method that would
work for everthing, both old and new collections. So, for dictionaries, I wrote
the following:

public static bool Equals(System.Collections.IDictionary d1,
                          System.Collections.IDictionary d2)
{
    bool result;

    // Try to determine equality based on reference equality
    // and number of elements first. This avoids the expensive
    // comparison of all elements.

    if(cheapComparison(d1, d2, out result))
    {
        return result;
    }

    // Need to compare all the entries after all, at O(n^2) cost.

    //
    // Get and sort both sets of keys. Keys are unique and non-null.
    //
    System.Collections.ICollection keys1 = d1.Keys;
    System.Collections.ICollection keys2 = d2.Keys;
    object[] ka1 = new object[d1.Count];
    object[] ka2 = new object[d2.Count];
    keys1.CopyTo(ka1, 0);
    keys2.CopyTo(ka2, 0);
    Array.Sort(ka1);
    Array.Sort(ka2);

    try
    {
        System.Collections.IEnumerator e = ka2.GetEnumerator();
        foreach(object o in ka1)
        {
            e.MoveNext();
            if(!o.Equals(e.Current))
            {
                return false;
            }
            if(!Equals(d1[o], d2[o]))
            {
                return false;
            }
        }
    }
    catch(System.Exception)
    {
        return false;
    }

    return true;
}

The array copy is necessary because I need to sort the keys, and I'm using the
generic version because, in the Ice run time, I have no idea what the actual
types involved are.

I haven't benchmarked this but, for large dictionaries, I suspect that the
array copy will account for an appreciable fraction of the total time.


-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.
_______________________________________________
mono-bugs maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-bugs

Reply via email to