西西河

主题:【原创】说说.NET 3.5中的高性能害死集--HashSet -- Highway

共:💬19 🌺63
全看树展主题 · 分页首页 上页
/ 2
下页 末页
家园 需要。.NET和Java在这个问题上完全一样

两者在collect garbage的具体手法上都非常相似。不过Java的tweak更多一些。

Java用的是HotSpot虚拟机。程序是“渐入佳境”。所以我执行Java程序的时候,要先“预热”一阵,并且测试量要相当的大,否则HotSpot还没掺和进去,结果看起来会很“惨”。

.NET没这个问题。所以不需要“预热”。执行时间再长程序也不会进一步优化。

家园 很有道理

的确如果底下用的hash table初始大小不同, load factor不同, 则比如Java 的开始第一次 realloc新表时, .NET还没到该点, 那末 realloc总是更耗时间.

不过本来hash map/set的使用, initial size and load factor 应该用户自调. 因为这两者跟实际问题密切相关, 无法普适. 另外一个跟实际问题相关的就是 hash function的选择, Java用的缺省 hasher跟 .NET的很可能不同.

另外有个想法, 如果怀疑是 Java object boxing, 说不定可以不用hash map/set, 直接测两者处理大集合整数, 看差别大不大.

家园 如果把HashMap的起始容量加大

就可以比较公平的比较Java 和 .Net 的HashMap 了。

家园 【致歉】Highway向大家道个歉

这篇文章写得有些仓促。问题叙述本身还没有大碍,但结论部分明摆着有问题。感谢虹道网友的几个问题,使我回过头来又看了一下我的测试程序和帖子。结果顿时冒汗。。。

点看全图

外链图片需谨慎,可能会被源头改

可能是写帖子的时候喝得有些高了,结论真是非常的草率。Java和.NET在Hash上的性能差距和Generics应该是没有关系的。Boxing, Casting也扯不上。误导大家,实在是不好意思。

本想好好把这个问题搞个清楚,给大家个说法。可是当深究这个问题的时候,发现还是有几个疑点很难一下子弄个水落石出的。并且这些天工作上忙得很,没有多少时间花在这个问题上了。这里再次向大家道个歉。等忙过这阵子了,一点写篇好点的东西,补偿一下。

往简单里说,HashMap,HashSet这些东西的关键是hashcode()和equals()两个函数。一个Object入住HashMap/HashSet的时候是先用自己的hash code找到相应的bucket,然后一个个的比过去(equals call)。这和在电影院对号入座有点像。进门的时候拿一个号,到了里面用这个号先找到是在哪一排,到了这排以后,从头上开始问起“劳驾,这里有人吗?”。直到找到一个空座,这才可以坐下来。这个找排依靠的是Hashcode,找座儿靠的是equals()函数。当一个HashMap,HashSet里面Object很多的情况下,每排就会有很多的人,要反复调用equals函数。这时候equals()函数的效率就成了关键。NET在整数上表现优异我觉得是它的equals()很简单(最简单的整数比较嘛),而Java比的是两个Integer Object,慢一些。两者Hashcode的逻辑是一模一样的。应该没有什么差距。在String操作上,.NET和Java的hashCode()和equals()实现都相差较大。.NET居然有微弱优势,这个倒是我没有想到的。

我这还只是个推论,没有从多个角度用数据证明,抱歉了。

全看树展主题 · 分页首页 上页
/ 2
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河