On 11/28/05 9:47 PM, "Tom Benson" <tombenson at mac dot com> wrote:
> Here's a project (5.5.5) that illustrates what I mean. It's rough and
> ready adaptation of your code versus my modified version or your
> code. My version is a bit slower, but I have yet to produce any hash
> collisions with it, whereas with your implementation I get 5-10
> before I even hit 5000 instances consistently.
>
> - Tom
>
If I understand what you're saying correctly, then the key lines of
importance which your code changes to solve this problem are:
varlist.append v
vhash = varlist(ubound(varlist)).hash
I.e. you generate the hash not from v, but from what I guess I'll call what
you believe to be a "copy" of it that is appended to varlist. Is this
correct?
====
Unfortunately, I was unable to run your project in RB 2005 v4 -- which is
the specific bug at hand. There were some screwy conversion problems with
the button and static text in the window. Perhaps if you send me a .xml
version of the file instead of the .rb file I can patch it together and run
the exact code you've put together. I was however able to read the MyMethod
and YourMethodp methods just fine, and I've incorporated the code from your
MyMethod method into my version of the program. A copy of the updated
source code is included below.
A few comments:
1) This code still fails with plenty of hash collisions.
2) Without testing the code in RB 2004 r4, you haven't really proved
anything. I'm equally as guilty for not having run my code under RB 5.x ...
which I'll endeavor to remedy tomorrow.
3) Since you never set the value of cNew in your code, the value of all the
dictionary entries is nil, which will generate a nil exception error the
first time you do hit a collision and it tries to create a message. I've
corrected this in my code below with the change:
CounterDict.value( vhash) = Counter( v )
4) Presumably you'll eventually convince me that there is something to this
and that the code I'm using is in error, or I'll eventually convince you
that this really is a bug in RB 2004 r4... it'll work itself out soon
enough. But for the sake of argument, let's say that you are correct.
Let's say that despite the fact that the test:
v is VariantList(ubound(VariantList))
most likely evaluates to "true" and that v.hash is necessarily therefore
identical to VariantList(ubound(VariantList)).hash as I believe to be the
case; that despite this there is indeed some sort of real problem here that
can only be solved by adding the entities to be hashed onto a special list
to preserve their existence and therefore their hash equivalence in the
manner you're suggesting...
If that is the case then I still have a real dilemma on my hands. Because
what I want to do is to obtain hashes for a ton of objects that are already
in existence, and well-entrenched in existing arrays already (well, trees
actually). I want to compare the hashes of THOSE objects, because THOSE are
the objects I want to do lookups and comparisons on -- not some separate
copies that get created and appended to a VariantsList for the purpose of
preserving their existence and making it possible to subsequently do hash
comparisons on representatives for the objects I already have at hand.
This is just another way of phrasing what I've said already a couple times
before. In the end, the casting or coercion or storage into Variants --
whatever you want to call it -- must necessarily not affect the value
returned by Variant.hash, or the function is essentially worthless. If this
limitation existed then you couldn't use Variant.hash to get the hash of an
arbitrary object, but merely the hash of what I'll call here a "Variant
copy" of the object. That serves no useful purpose, and if it were true
then -- as Joe points out -- Dictionaries which rely on such hashes simply
could not work.
So in the end, as I say, we'll come to terms with what the code is really
doing or not doing in various versions. But I'm essentially making an
argument based on fundamental principles that says the distinction you are
attempting to show in your code necessarily CAN NOT make a difference --
because if it does, we're all in deep doo doo.
I of course look forward to a lively rebuttal pointing out all the obvious
flaws in this reasoning. ;-)
=========
Here's my revised code:
=========
dim cNew, cOld as Counter
CounterDict = new Dictionary
dim v as variant
dim vHash as integer
dim i as integer
dim message as string
const maxCollisions = 10
dim collisionCt as integer
const countModulus = 100
for i = 0 to 10000
if i Mod countModulus = 0 then
EditField3.text = str( i )
app.DoEvents
end
'cNew = new Counter( i )
'v = cNew
'CounterList.append cNew
'VariantList.append v
'vhash = v.hash
v = new Counter( i )
VariantList.append v
vhash = VariantList(ubound(VariantList)).hash
if CounterDict.hasKey( vhash ) then
cOld = Counter( CounterDict.value( vHash ) )
message = message + _
"Hash of Counter " + str( i ) + " = hash of counter " + _
str( cOld.count ) + EndOfLine
collisionCt = collisionCt + 1
Editfield2.text = message
if collisionCt = maxCollisions then exit
else
'CounterDict.value( vhash ) = cNew
CounterDict.value( vhash ) = Counter( v )
end
next
'if collisionCt > 0 then
'break // Examine the properties in the debugger based on message
'end
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>
Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>
|