中間件團隊組織的Coding4Fun的第三期已經結束,這次參與的同學很活躍,報名的有20多人,最終有17人在gitlab上送出了代碼。把這次活動以及大家的經驗總結一下。
任務:
裡有一個大文本,檔案請從 http://10.125.9.144:8000/document.zip 擷取,在解壓後大約有20m(實際比賽時檔案是1.1G)。 文本中都是英文單詞,空格以及英文的标點符号: [.,;-~"?'!] (句号,逗号,分号,破折号,波浪号,雙引号,問号,單引号,感歎号)
請統計出該文本中最常出現的前10個單詞(不區分大小寫)。 請注意,在統計中這20個單詞請忽略(the, and, i, to, of, a, in, was, that, had, he, you, his, my, it, as, with, her, for, on)
說明:
1) 程式設計語言不限
2) 最終的測試機器為多核環境(單機)
3) 不得借助外部服務(調用遠端服務)
4) 可引用外部架構或庫(限開源)
5) 結果不正确直接淘汰
6) 用時最短者獲勝(前三名有獎)
7) 代碼優雅凝練(明顯比前三名的代碼量少且易懂)并且性能不太離譜,可獲最佳代碼獎
因為此次不限程式設計語言,為避免不同語言的運作時/虛拟機啟動時間差異,沒有統一的計時方式,計時方式為在main的入口和出口自行統計。在比賽的機器上(linux系統,16核,8G記憶體)運作3次,取時間最短的那次做最終成績。
最終獲獎結果:
澗泉:1936ms c++
子觀:2489ms c++
雪酒:2565ms c++
玄胤:2615ms c
平威:2792ms java
劈空:2860ms c++
遊骥:3207ms java
長源:3220ms java
叔至:3334ms java
寒玄: 4336ms go
娜米: 4分32秒 perl 一行代碼
第一名:澗泉,唯一突破2秒的,獎品是機械鍵盤
他采用并發方式,用
ConcurrentTrieNode
實作了線程安全的
Trie
樹。詳細經驗見:wordcount設計與優化。澗泉同學很低調,在Coding4Fun的交流群裡也很沉默,不過看到他blog裡說的,就能體會到一個追求完美的碼農的心态了:
程式開始是用JavaConcurrentHashMap實作的。為了提升性能翻譯成C++,過程可謂大費周折,相當痛苦,我會告訴你我大半夜還在調segmentalfault嗎?

第二名:子觀
子觀同學也是一匹黑馬,剛開始用python實作的,成績幾乎墊底;在送出代碼的前一天晚上通宵debug,實作了大逆轉。
子觀的經驗見:coding4fun比賽總結
第三名:雪酒
雪酒同學暑期來阿裡實習,8月底選擇了回學校讀研究所學生,我們會把T恤寄給你,也歡迎有空回來轉轉。他的經驗如下:
政策1:盡最大的努力減少動态申請記憶體
理由:在初始實驗之中,我是每分離出一個單詞就要malloc記憶體,時間就花銷很長,因為這種小記憶體的配置設定的時候,系統會好很長的時間,而且容易産生記憶體碎片,于是我就想到了盡量減少malloc的使用,在程式實作之中,除了第一次malloc了一個與檔案一樣大的記憶體外,從此沒有使用過malloc函數,還好如今的gcc支援c99,可以讓我預先定義動态數組,這樣子我除了那個在堆上的總buffer,其餘的存儲變量幾乎都是在棧上,不僅僅節約了時間,而且讓我減少了對記憶體的管理。
政策2:hash表和trie樹同時使用
理由:trie樹的優點就不用說了,查找是很快的,缺點是比較的明顯,第一,耗記憶體,第二還是耗記憶體,由于我采用了政策1的政策,是以,我不能再每個字母節點都malloc記憶體,我一開始就把我的trie樹大小給定死了的,當trie樹需要節點的時候,就直接按照預先在靜态區分好了的給,如果超過了預先定的數目,那麼就段錯誤了……=。=,由于trie樹比較耗記憶體,是以我就不想每個線程都來一個trie樹,萬一記憶體使用過多,導緻頻繁的換頁那就虧大了。是以,我在主線程中使用的trie樹,其餘線程中,使用的是hash表,這樣子就能大規模的減少程序對記憶體的占用了(雖然我一口氣吃的記憶體也是很多),而且trie樹和hash表同時使用還可以利用trie樹查找快的這麼一個特點(其實作在也不能确定trie樹是否能比hash快)。
政策3:待排序的數組去除掉無用的,空的節點
理由:若是使用hash表,我最後排序的時候中間會出現很多的空的節點,把這些空節點一起算進來進行排序的話會有一部分排序是無意義的,要是一開始使用沒有無意義的節點的數組,那麼就可以減少不必要的循環。
第四名:玄胤
玄胤同學是利用openMP的并行庫+無鎖hashtable來實作的,詳見:c4f玄胤總結,玄胤同學除了會寫代碼,還會彈彈琴什麼的,文藝青年一枚
簡潔代碼獎:娜米
娜米是此次比賽裡唯一的女生,很偷懶的就用了一行perl程式解決了,雖然效率差了幾個數量級,但據說娜米妹子也是精通算法的,隻是這次比賽沒投入精力。娜米憑她的古靈精怪獲得了最簡潔代碼獎,希望下次有更多的妹子參與。
這次比賽很熱鬧,沒有語言的限制,C/C++,Java,Go,Erlang,Python,Perl等百花齊放。最後來一張獲獎者合照(有個别同學沒在):
補充,長源和平威用java實作的性能也很不錯,大力推薦一下。