快手KCode比赛心得

题目与参赛代码:https://github.com/AllenDuke/kcode

 

这应该是我第一次参加计算机类比赛,除开学校举办的程序设计赛的话。我能感觉到自己的水平提升了很多,学到了解决问题可从多个角度入手,尝试,用多个指标来衡量,然后挑出最优角度,最后从这个角度再出发,不断优化。

一般我的思路如下:

先用单线程读取与处理,如果可以先做流式计算,不过最后还是要和一次性读入进行比较。

再考虑更换好的数据结构和算法,接着更换为多线程并行计算。

利用特征,减少不必要运算,如不判断是否为空,特别是要注意重写equal和hashCode方法,优化必要运算,如利用位运算,或者在某些特定场景下用加法代替乘法。

重用对象,减少对象的产生,减轻gc,为此我自己设计了一个可重用的SDS来代替字符串拼接和StringBuilder,但似乎拼接的量少时,如3个,拼接的速度更快。

在内存足够时,增加冗余来减少连接,增加索引来减少无效遍历。

 

应该是止步复赛了,但我既不服气又服气。复赛线上用的应该是机械硬盘,多线程处理没有帮助,反而会加重IO负担,那么大家都只能单线程处理了(但我认为自己在多线程上有优势的),估计一阶段大家都应该是差不多的,那么都在拼二阶段了。在优化二阶段的过程中,我想到了在一阶段中提前查询来预热数据,那么二阶段就可以直接获取了,接着优化,我还想到了在(StringA,StringB)->StringC时,转换为Long->StringC,Long的高32位保存StringA的hashCode,低32位保存StringB的hashCode,减少String.hashCode运算,当然这是有hash冲突的风险的。最后我还想到了定制一个IntHashMap和LongHashMap用于确定key位int为long的情况,以减少Integer和Long的产生,减少equal的无用判断。至此我认为自己已经优化到极限了,然而还是比不上大佬们。

我不服气的是,我自认为的极限却还是看不到大佬们的身影,我不服气的是大佬们轻易想到用数组(我用的是Map,还没有测试速度差了多少)和神奇的hash函数(我有尝试过更换好的hash函数,但总会冲突),我不服气的是,最后竟要输在纳秒级别的差异上。

我服气的是,大佬之所以是大佬,是因为大佬在什么时间,什么地点都是大佬。

不过我还是挺满意的,因为在我自己看来,我有了很大的突破,而这种突破不会停止。在大佬们的讨论和开源的代码中,我学习到了很多,除了上述所说的神奇的hash函数外,还有JNI和各种优化手段,是很感激的!

 

不以物喜,不以己悲,继续学习。

 

8.2 更新

今天看到了大佬开源的复赛代码,对大佬是更加佩服了,认识到自己与大佬的差距是多么的大(不止hash函数,io处理也有较大差距),不过也知道了自己进步的空间与进步的方向、方法,再次感谢他们!

posted @ 2020-07-17 23:55  Allen没有青春  阅读(405)  评论(0编辑  收藏  举报