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.

Saeed Amiri
  • 22,252
  • 5
  • 45
  • 83
Masoud
  • 1,354
  • 6
  • 18
  • 30
  • 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). – CARLOS LOTH Jan 08 '11 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? – Masoud Jan 08 '11 at 14:35

3 Answers3

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.

Saeed Amiri
  • 22,252
  • 5
  • 45
  • 83
  • 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. – Masoud Jan 08 '11 at 14:18
  • @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 Jan 08 '11 at 14:32
  • @ 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 Amiri Jan 08 '11 at 14:37
  • @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. – Masoud Jan 08 '11 at 14:40
  • @Saeed: thanks for editing for my post to a more readable one. – Masoud Jan 08 '11 at 14:41
  • @Masoud, So you can check just first item of your array, or in creation of your object create NewGuid, and make it your object id and return this Guid's hash code. – Saeed Amiri Jan 08 '11 at 14:44
  • They are not possible. Because the array is not so flexible. Maybe only 1 or two item of array is changing in every case. – Masoud Jan 08 '11 at 14:48
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).

CARLOS LOTH
  • 4,675
  • 3
  • 38
  • 44
  • 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! – Masoud Jan 08 '11 at 14:21
  • 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. – CARLOS LOTH Jan 08 '11 at 14:35
  • 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? – Masoud Jan 08 '11 at 14:38
  • 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. – CARLOS LOTH Jan 08 '11 at 14:50
  • 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. – Masoud Jan 08 '11 at 15:04
  • I don't have visibility of the entire problem your trying to solve, so it is likely I have not understood your question well. I thought you are using the hashing only for perfoming evaluations on small a part of your code. But if you are using if for other purpose, such as caching, and the arrays are mutable, use their contents for hashing is not a good idea. – CARLOS LOTH Jan 08 '11 at 15:12
1

Comparing object properties in c#

Community
  • 1
  • 1
abmv
  • 7,042
  • 17
  • 62
  • 100
  • 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. – Masoud Jan 08 '11 at 14:20