电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Java 5億整數大文件怎么排序

瀏覽:79日期:2022-09-03 18:08:44

問題

給你1個文件bigdata,大小4663M,5億個數,文件中的數據隨機,如下一行一個整數:

61963023557681612158020393452095006174677379343122016371712330287901712966901...7005375

現在要對這個文件進行排序,怎么搞?

內部排序

先嘗試內排,選2種排序方式:

3路快排:

private final int cutoff = 8;public <T> void perform(Comparable<T>[] a) { perform(a,0,a.length - 1); } private <T> int median3(Comparable<T>[] a,int x,int y,int z) { if(lessThan(a[x],a[y])) { if(lessThan(a[y],a[z])) {return y; } else if(lessThan(a[x],a[z])) {return z; }else {return x; } }else { if(lessThan(a[z],a[y])){return y; }else if(lessThan(a[z],a[x])) {return z; }else {return x; } } } private <T> void perform(Comparable<T>[] a,int low,int high) { int n = high - low + 1; //當序列非常小,用插入排序 if(n <= cutoff) { InsertionSort insertionSort = SortFactory.createInsertionSort(); insertionSort.perform(a,low,high); //當序列中小時,使用median3 }else if(n <= 100) { int m = median3(a,low,low + (n >>> 1),high); exchange(a,m,low); //當序列比較大時,使用ninther }else { int gap = n >>> 3; int m = low + (n >>> 1); int m1 = median3(a,low,low + gap,low + (gap << 1)); int m2 = median3(a,m - gap,m,m + gap); int m3 = median3(a,high - (gap << 1),high - gap,high); int ninther = median3(a,m1,m2,m3); exchange(a,ninther,low); } if(high <= low) return; //lessThan int lt = low; //greaterThan int gt = high; //中心點 Comparable<T> pivot = a[low]; int i = low + 1; /* * 不變式: * a[low..lt-1] 小于pivot -> 前部(first) * a[lt..i-1] 等于 pivot -> 中部(middle) * a[gt+1..n-1] 大于 pivot -> 后部(final) * * a[i..gt] 待考察區域 */ while (i <= gt) { if(lessThan(a[i],pivot)) {//i-> ,lt ->exchange(a,lt++,i++); }else if(lessThan(pivot,a[i])) {exchange(a,i,gt--); }else{i++; } } // a[low..lt-1] < v = a[lt..gt] < a[gt+1..high]. perform(a,low,lt - 1); perform(a,gt + 1,high); }

歸并排序:

/** * 小于等于這個值的時候,交給插入排序 */ private final int cutoff = 8; /** * 對給定的元素序列進行排序 * * @param a 給定元素序列 */ @Override public <T> void perform(Comparable<T>[] a) { Comparable<T>[] b = a.clone(); perform(b, a, 0, a.length - 1); } private <T> void perform(Comparable<T>[] src,Comparable<T>[] dest,int low,int high) { if(low >= high) return; //小于等于cutoff的時候,交給插入排序 if(high - low <= cutoff) { SortFactory.createInsertionSort().perform(dest,low,high); return; } int mid = low + ((high - low) >>> 1); perform(dest,src,low,mid); perform(dest,src,mid + 1,high); //考慮局部有序 src[mid] <= src[mid+1] if(lessThanOrEqual(src[mid],src[mid+1])) { System.arraycopy(src,low,dest,low,high - low + 1); } //src[low .. mid] + src[mid+1 .. high] -> dest[low .. high] merge(src,dest,low,mid,high); } private <T> void merge(Comparable<T>[] src,Comparable<T>[] dest,int low,int mid,int high) { for(int i = low,v = low,w = mid + 1; i <= high; i++) { if(w > high || v <= mid && lessThanOrEqual(src[v],src[w])) {dest[i] = src[v++]; }else {dest[i] = src[w++]; } } }

數據太多,遞歸太深 ->棧溢出?加大Xss? 數據太多,數組太長 -> OOM?加大Xmx?

耐心不足,沒跑出來.而且要將這么大的文件讀入內存,在堆中維護這么大個數據量,還有內排中不斷的拷貝,對棧和堆都是很大的壓力,不具備通用性。

sort命令來跑

sort -n bigdata -o bigdata.sorted

跑了多久呢?24分鐘.

為什么這么慢?

粗略的看下我們的資源: 1. 內存 jvm-heap/stack,native-heap/stack,page-cache,block-buffer 2. 外存 swap + 磁盤

數據量很大,函數調用很多,系統調用很多,內核/用戶緩沖區拷貝很多,臟頁回寫很多,io-wait很高,io很繁忙,堆棧數據不斷交換至swap,線程切換很多,每個環節的鎖也很多.

總之,內存吃緊,問磁盤要空間,臟數據持久化過多導致cache頻繁失效,引發大量回寫,回寫線程高,導致cpu大量時間用于上下文切換,一切,都很糟糕,所以24分鐘不細看了,無法忍受.

位圖法

private BitSet bits; public void perform( String largeFileName, int total, String destLargeFileName, Castor<Integer> castor, int readerBufferSize, int writerBufferSize, boolean asc) throws IOException { System.out.println('BitmapSort Started.'); long start = System.currentTimeMillis(); bits = new BitSet(total); InputPart<Integer> largeIn = PartFactory.createCharBufferedInputPart(largeFileName, readerBufferSize); OutputPart<Integer> largeOut = PartFactory.createCharBufferedOutputPart(destLargeFileName, writerBufferSize); largeOut.delete(); Integer data; int off = 0; try { while (true) {data = largeIn.read();if (data == null) break;int v = data;set(v);off++; } largeIn.close(); int size = bits.size(); System.out.println(String.format('lines : %d ,bits : %d', off, size)); if(asc) {for (int i = 0; i < size; i++) { if (get(i)) { largeOut.write(i); }} }else {for (int i = size - 1; i >= 0; i--) { if (get(i)) { largeOut.write(i); }} } largeOut.close(); long stop = System.currentTimeMillis(); long elapsed = stop - start; System.out.println(String.format('BitmapSort Completed.elapsed : %dms',elapsed)); }finally { largeIn.close(); largeOut.close(); } } private void set(int i) { bits.set(i); } private boolean get(int v) { return bits.get(v); }

nice!跑了190秒,3分來鐘. 以核心內存4663M/32大小的空間跑出這么個結果,而且大量時間在用于I/O,不錯.

問題是,如果這個時候突然內存條壞了1、2根,或者只有極少的內存空間怎么搞?

外部排序

該外部排序上場了. 外部排序干嘛的?

內存極少的情況下,利用分治策略,利用外存保存中間結果,再用多路歸并來排序; map-reduce的嫡系.

Java 5億整數大文件怎么排序

Java 5億整數大文件怎么排序

1.分

內存中維護一個極小的核心緩沖區memBuffer,將大文件bigdata按行讀入,搜集到memBuffer滿或者大文件讀完時,對memBuffer中的數據調用內排進行排序,排序后將有序結果寫入磁盤文件bigdata.xxx.part.sorted. 循環利用memBuffer直到大文件處理完畢,得到n個有序的磁盤文件:

Java 5億整數大文件怎么排序

2.合

現在有了n個有序的小文件,怎么合并成1個有序的大文件? 把所有小文件讀入內存,然后內排? (⊙o⊙)… no!

利用如下原理進行歸并排序:

Java 5億整數大文件怎么排序

我們舉個簡單的例子:

文件1:3,6,9 文件2:2,4,8 文件3:1,5,7

第一回合: 文件1的最小值:3 , 排在文件1的第1行 文件2的最小值:2,排在文件2的第1行 文件3的最小值:1,排在文件3的第1行 那么,這3個文件中的最小值是:min(1,2,3) = 1 也就是說,最終大文件的當前最小值,是文件1、2、3的當前最小值的最小值,繞么? 上面拿出了最小值1,寫入大文件.

第二回合: 文件1的最小值:3 , 排在文件1的第1行 文件2的最小值:2,排在文件2的第1行 文件3的最小值:5,排在文件3的第2行 那么,這3個文件中的最小值是:min(5,2,3) = 2 將2寫入大文件.

也就是說,最小值屬于哪個文件,那么就從哪個文件當中取下一行數據.(因為小文件內部有序,下一行數據代表了它當前的最小值)

最終的時間,跑了771秒,13分鐘左右.

less bigdata.sorted.text...9999966999996799999689999969999997099999719999972999997399999749999975999997699999779999978...

到此這篇關于Java 5億整數大文件怎么排序的文章就介紹到這了,更多相關Java 大文件排序內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
主站蜘蛛池模板: 菲希尔X射线测厚仪-菲希尔库伦法测厚仪-无锡骏展仪器有限责任公司 | 奥运星-汽车性能网评-提供个性化汽车资讯 | 微信聊天记录恢复_手机短信删除怎么恢复_通讯录恢复软件下载-快易数据恢复 | 999范文网_优质范文下载写作帮手 | 电伴热系统施工_仪表电伴热保温箱厂家_沃安电伴热管缆工业技术(济南)有限公司 | 防堵吹扫装置-防堵风压测量装置-电动操作显示器-兴洲仪器 | 自动钻孔机-全自动数控钻孔机生产厂家-多米(广东)智能装备有限公司 | 烟台螺纹,烟台H型钢,烟台钢材,烟台角钢-烟台市正丰金属材料有限公司 | 上海办公室装修_上海店铺装修公司_厂房装潢设计_办公室装修 | 北京发电车出租-发电机租赁公司-柴油发电机厂家 - 北京明旺盛安机电设备有限公司 | 岸电电源-60HZ变频电源-大功率变频电源-济南诚雅电子科技有限公司 | 3d打印服务,3d打印汽车,三维扫描,硅胶复模,手板,快速模具,深圳市精速三维打印科技有限公司 | 咖啡加盟,咖啡店加盟连锁品牌-卡小逗 | 校园文化空间设计-数字化|中医文化空间设计-党建|法治廉政主题文化空间施工-山东锐尚文化传播公司 | 胀套-锁紧盘-风电锁紧盘-蛇形联轴器「厂家」-瑞安市宝德隆机械配件有限公司 | 都江堰招聘网-都江堰人才网 都江堰人事人才网 都江堰人才招聘网 邢台人才网_邢台招聘网_邢台123招聘【智达人才网】 | 焊缝跟踪系统_激光位移传感器_激光焊缝跟踪传感器-创想智控 | Q361F全焊接球阀,200X减压稳压阀,ZJHP气动单座调节阀-上海戎钛 | 合肥展厅设计-安徽展台设计-合肥展览公司-安徽奥美展览工程有限公司 | pbt头梳丝_牙刷丝_尼龙毛刷丝_PP塑料纤维合成毛丝定制厂_广州明旺 | 垃圾清运公司_环卫保洁公司_市政道路保洁公司-华富环境 | 免费分销系统 — 分销商城系统_分销小程序开发 -【微商来】 | 六自由度平台_六自由度运动平台_三自由度摇摆台—南京全控科技 | 旗杆生产厂家_不锈钢锥形旗杆价格_铝合金电动旗杆-上海锥升金属科技有限公司 | 贵州科比特-防雷公司厂家提供贵州防雷工程,防雷检测,防雷接地,防雷设备价格,防雷产品报价服务-贵州防雷检测公司 | 广州/东莞小字符喷码机-热转印打码机-喷码机厂家-广州瑞润科技 | 成都治疗尖锐湿疣比较好的医院-成都治疗尖锐湿疣那家医院好-成都西南皮肤病医院 | 皮带式输送机械|链板式输送机|不锈钢输送机|网带输送机械设备——青岛鸿儒机械有限公司 | 对夹式止回阀_对夹式蝶形止回阀_对夹式软密封止回阀_超薄型止回阀_不锈钢底阀-温州上炬阀门科技有限公司 | 定做大型恒温循环水浴槽-工业用不锈钢恒温水箱-大容量低温恒温水槽-常州精达仪器 | 皮带式输送机械|链板式输送机|不锈钢输送机|网带输送机械设备——青岛鸿儒机械有限公司 | 纳米涂料品牌 防雾抗污纳米陶瓷涂料厂家_虹瓷科技 | 低粘度纤维素|混凝土灌浆料|有机硅憎水粉|聚羧酸减水剂-南京斯泰宝 | 山东太阳能路灯厂家-庭院灯生产厂家-济南晟启灯饰有限公司 | 气动隔膜泵厂家-温州永嘉定远泵阀有限公司 | 布袋式除尘器|木工除尘器|螺旋输送机|斗式提升机|刮板输送机|除尘器配件-泊头市德佳环保设备 | 铜镍-康铜-锰铜-电阻合金-NC003 - 杭州兴宇合金有限公司 | 真空干燥烘箱_鼓风干燥箱 _高低温恒温恒湿试验箱_光照二氧化碳恒温培养箱-上海航佩仪器 | 27PR跨境电商导航 | 专注外贸跨境电商 | 密集架-密集柜厂家-智能档案密集架-自动选层柜订做-河北风顺金属制品有限公司 | 大行程影像测量仪-探针型影像测量仪-增强型影像测量仪|首丰百科 大通天成企业资质代办_承装修试电力设施许可证_增值电信业务经营许可证_无人机运营合格证_广播电视节目制作许可证 |