0

I have lots of objects. I should evaluate one of thier members.them one by one. The first is evaluating them one by one --------> pseudo code

while (anyObjectExists)
{
      Class1 obj = getObject();
      double evalNum = eval(obj.member1);
}

but eval is a time consuming method. and lots of objects have same member1. member1 is an array of type sbyte. So I tried to ind another way. That was my way: ------->pseudo code

HashTable evaluatedObject = new HashTable();
while(anyObjectExists)
{
      Class1 obj = getObject();
      if (evaluatedObjects.Contain(obj))
      {
            double evalNum = evaluatedObjects[obj];
      }
      else
      {
            double evalNum = eval(obj.member1);
            evaluatedObjects.Add(obj, evalNum);
      }
}

I knew that I should override getHashCode and Equals method for sbyte. As you can see the eval method only uses member1 from Class1. So I added to methods to my Class1 in this way

    public override int GetHashCode()
    {
        return 1;
    } 
    public override bool Equals(Object compareState)
    {
        if (!this.member1.SequenceEqual(((Class1)compareState).member1))
            return false;
        return true;
    }

Ok. I thought it is done. But when I run my program ... it is a god damn slow program. It is a lot slower than the first program. I tested it. It can find added objects. There is nothing wrong about it. But it is very very slow. I though hash can retrieve data in 1 or 2 shot. What did I wrong?

Any help would be highly welcomed.

2
  • 1
    I think it is evaluatedObjects.Contain(obj) statement that is causing your code to slowdown. All your objects has the same key (the same hash code) what makes your hash table be the same as a linked list. In that case your search will have a complexity of O(N) instead of O(1). Commented Jan 8, 2011 at 14:13
  • Yes. \o/ that is right. But how can I change getHashCode method for a sbyte array to return same value for an array and it's cloned version? Commented Jan 8, 2011 at 14:35

3 Answers 3

2

You should return a valid hash code, like this.member1.Count().GetHashCode() not 1, in your case it always compare them by their hash and because they are a same compare them by their equal, and your function runs slower.

Edit: Also I think your eval function is faster than your work on sequence equals. in fact your (Class1)compareState is time consuming and also your sequence comparison is time consuming too.

Sign up to request clarification or add additional context in comments.

7 Comments

No. It is not needed to set a valid hash code. Because it will use equals method after checking hash code. So it will work OK. And for setting a valid hash code: I had to same arrays I get their hash code and that was different!!! I couldn't find another way.
@Saeed. I used clone method. ---->pseudo code: sbyte[] array1 = new sbyte[100]; array1.setValues(); sbyte[] array2 = (sbyte[])array1.Clone(); and array1.getHashCode is not equal with array2.getHashCode(); Thanks for your contribution
@ Masoud, yes because they are different objects, MSDN offered using uniqe stable hashcode for each object, what's wrong here? I think you missed my point about Count() (I saying that hash code which is changing in lifetime of object is not good, but in your case is not bad)
@Saeed: Becuase count method is only depend on length of my array. It is a fixed array so hashtable will put all of them in one bucket.
@Saeed: thanks for editing for my post to a more readable one.
|
2

Do not fix the HashCode to 1, because it will make necessary for the data structures that relies on hashing to handle a bunch of collisions. In this case there will be no difference between using a hash table or a linked list. When searching for an object (by calling the Cointains method, for instance), it will be necessary to evaluate each object in your collection, complexity O(N), instead of accessing the object by its hash code, complexity O(1).

6 Comments

I couldn't find a better way. As I said member1 is an array of type sbyte. When I compare hash code of two same member1 they are not the same!
The problem is you are storing the Class1 instances into a HashTable, and all of these objects has their hashcode = 1. Maybe I understood it wrongly, but it still seems to me that your performance lack happens at evaluatedObjects.Contain(obj) statement.
Yes. \o/ that is right. But how can I change getHashCode method for a sbyte array to return same value for an array and it's cloned version?
It depends, you can use one of its singularities for specifying the hash code. For example, you can use as your hash code the length of the array, but I don't think it would be a good idea. Why don't you take the first 3 elements and combining them by using the XOR operator? return a[0] ^ a[1] ^ a[2];. Let's give it a try.
It couldn't be applied. Because arrays may change in any part. And may be the same in lots of other parts. So using a[0], a[1] and a[2] won't help.
|
1

Comparing object properties in c#

1 Comment

the equal function I wrote is working write. I made an object from class 1 function. And I made another one after it that its member1 was just like the first one. .Equals returned me true.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.