博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
排序比赛的回顾
阅读量:5095 次
发布时间:2019-06-13

本文共 1102 字,大约阅读时间需要 3 分钟。

偶见有人在发起一个排序比赛,对27W左右的词进行排序输出,要求读取+排序+输出的时间最少。

 

例子代码有一个简单的Java版本实现,大概的时间是在4xxms,然后是Go语言实现,大约在3XX ms。Go语言不懂,就不折腾了。Java的版本还是可以看看。时间分布上,读取2.8M的文件大约150ms,写大约100毫秒,感觉明显可以优化。

第一步,修改读取方法,使用NIO的内存映射,直接开内存读取,时间下降到70ms,写入50ms左右,合计300多一点

第二步,修改排序算法,修改原来的多线程,对读取的时候数据进行分组,各个线程直接排序即可,最后再归并,总时间下降到260ms左右

第三步,尝试了读取的时候就分给多线程去插入SortedTree,归并输出,效果不明显,没什么提升。

第四步,尝试Java的Fork/Join调度框架,优化线程,可惜没写好,只当成多线程在用,提升了一点点。

第五步,修改了Fork/Join的分组部分,递归方式分组,方便一个线程执行完自己任务后,可帮助执行其他任务,避免全局的Join等待, 优化提升到了233ms左右 

第四步,去掉了NIO读取逻辑,直接开BYTE数组读取,写入也类似, IO时间下降到10ms,夸张啊,是否使用BufferReader几乎没影响。总体时间下降到140 ms左右,还是非常明显的提升。

第五步,发现很用同学的时间已经进入100ms以内了,我优化了排序逻辑,主要的时间消耗在String比较上,根据文件特点,我优化了排序的比较逻辑,读取的时候就对ascii进行转义,long64位,short16位,文件的最大字符串长度为15,且不重复。这一点好像有点作弊,应该有一段逻辑进行探测计算才正规。每5位可以表示任何一个a~z,后面补0,这样位移消耗不大,且方便比较。只是Java无符号型处理起来麻烦,我C#也比较熟悉,就改C#写了。,先比前long,一样的情况下才比后面的short,时间:12+38+10=60ms左右,有点累了,还有项目的工作要做。

这个时候,我忽悠了跟多人进来,希望看到更好的结果。开始的方案,大家都差不多,多线程+快排,时间也你追我赶。后面GCC的优势开始起来,类似的思路,开始在多核上排序,47ms,44ms,41ms...

  临近比较收官,忽悠到了YW的参与,第二日只用了不到300行的代码,成绩46ms,优化后,进入33ms,原来的第一名开始坐不住了,优化。。。最后的成绩22ms,

 

 

 

转载于:https://www.cnblogs.com/diudiu3721/archive/2012/10/17/2727654.html

你可能感兴趣的文章
centos7 安装SVN
查看>>
【ZH奶酪】如何用sklearn计算中文文本TF-IDF?
查看>>
USACO Shaping Regions,难题,离散化,矩形切割,逆序染色
查看>>
iis 还原配置
查看>>
设计模式——门面模式
查看>>
自己动手打造工具系列之自动刷新简历
查看>>
Sqlserver2005附加数据库为只读的解决方法
查看>>
[BZOJ 1296] 粉刷匠
查看>>
C#将文档(Word\ Excel\ PowerPoint\ Visio\ text\ XML\ RTF\ CSV )转成Pdf
查看>>
redis报错
查看>>
重载delete时的那点事
查看>>
页面请求后台方法,报错Session error
查看>>
详解三层架构图
查看>>
OpenCV - Android Studio 2.2 中利用CAMKE进行OpenCV的NDK开发
查看>>
Frameworks.Entity.Core 4
查看>>
JavaEE--调用 WSDL -- httpclient 4.x.x
查看>>
Digital Communication and signal processing (30059)
查看>>
Oracle Block scn/commit scn/cleanout scn 说明
查看>>
mysql全文检索
查看>>
struts2 请求参数接收
查看>>