日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

lambdas for_Wordcounter,使用Lambdas和Fork / Join计算Java中的单词数

發(fā)布時(shí)間:2023/12/3 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lambdas for_Wordcounter,使用Lambdas和Fork / Join计算Java中的单词数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

lambdas for

這些天來(lái),我發(fā)布了Wordcounter ,這是一個(gè)Java庫(kù)和命令行實(shí)用程序,用于對(duì)文本文件中的單詞進(jìn)行計(jì)數(shù)并對(duì)單詞計(jì)數(shù)進(jìn)行分析,從而大量使用了功能編程結(jié)構(gòu)和并行計(jì)算方法。 這是我在“令人討厭的快速問(wèn)答”大賽第四個(gè)條目SAP ,經(jīng)過(guò)給料機(jī) , 托多爾和Hanoier 。

該庫(kù)使用JDK 8 lambda ,以及新的JDK 7功能,例如Fork / Join和NIO.2 。 它是內(nèi)置的,只能與支持lambda的JDK 8的早期訪問(wèn)版本一起使用 。

隨著JDK 8中l(wèi)ambda及其支持功能的引入,我們用Java構(gòu)建軟件的方式將發(fā)生變化。 如果您想了解幾年后Java代碼的外觀,可以看看Wordcounter。 與當(dāng)前大多數(shù)可用資源不同,這不是簡(jiǎn)單的教程,而是一個(gè)實(shí)際的項(xiàng)目。

競(jìng)賽任務(wù)要求使用Fork / Join和lambdas實(shí)現(xiàn)算法,該算法分析目錄中的所有文件并查找文件中十個(gè)最常用的單詞以及它們出現(xiàn)的次數(shù)。 我沒(méi)有簡(jiǎn)單地堅(jiān)持使用Fork / Join,而是嘗試找到最適合此任務(wù)的并行方法,這使我選擇了Producer / Consumer作為核心的單詞計(jì)數(shù)邏輯。

您可以在github上探索源代碼。 還有一個(gè)相當(dāng)全面的自述文件,提供了更詳細(xì)的文檔。

最新的二進(jìn)制,javadoc和源代碼包可在GitHub 下載部分中找到 。 如果有足夠的興趣,我將在線發(fā)布Javadoc,并在中央Maven存儲(chǔ)庫(kù)中提供該庫(kù)。

歡迎提供反饋,評(píng)論和貢獻(xiàn)!

總覽

圖書館特色

  • 計(jì)算字符串,單個(gè)文本文件或包含文本文件的目錄樹中的所有單詞。
  • 分析單詞計(jì)數(shù)以找到前N個(gè)最常用的單詞,后N個(gè)最不常用的單詞或總單詞數(shù)。
  • 通過(guò)外部謂詞指定字符是否為文字字符。
  • 指定要對(duì)單詞執(zhí)行的可選操作,例如通過(guò)外部運(yùn)算符轉(zhuǎn)換為小寫字母。
  • 在非并行和并行實(shí)現(xiàn)之間進(jìn)行選擇,以比較其性能。
  • 如果需要,將并行度指定為與內(nèi)核數(shù)不同的值。

編程要點(diǎn)

  • 使用生產(chǎn)者/使用者來(lái)讀取文件并并行計(jì)算每個(gè)文件中的單詞。 實(shí)際的機(jī)制封裝在通用的可重用實(shí)現(xiàn)中。
  • 使用Fork / Join對(duì)字?jǐn)?shù)進(jìn)行分析。 這里,實(shí)際的機(jī)制再次封裝在通用的可重用實(shí)現(xiàn)中。
  • 使用NIO.2遍歷目錄樹和讀取文件。
  • 大量使用函數(shù)接口和lambda表達(dá)式 ,以便在適當(dāng)?shù)牡胤絺鬟f函數(shù)而不是數(shù)據(jù)。
  • 有兩個(gè)最重要的類的綜合單元測(cè)試和性能測(cè)試。
  • 像往常一樣,該代碼干凈,結(jié)構(gòu)合理且易于閱讀。 格式,命名和注釋是統(tǒng)一且一致的。 適當(dāng)?shù)厥褂昧嗣嫦驅(qū)ο蠛凸δ芫幊碳夹g(shù)已經(jīng)引起了很多關(guān)注。

命令行界面

要啟動(dòng)命令行程序,請(qǐng)執(zhí)行以下命令:

java -jar wordcounter-1.0.4.jar <options>

所有選項(xiàng)都有合理的默認(rèn)值,因此都不是必需的。 對(duì)所有選項(xiàng)使用默認(rèn)值會(huì)導(dǎo)致在當(dāng)前目錄及其子目錄中找到前10個(gè)最常用的單詞。 指定非默認(rèn)值允許指定不同的目錄,分析模式,單詞字符,單詞數(shù)和并行度,以及忽略大小寫或使用串行而不是并行計(jì)算,例如:

在“單詞”目錄中找到最常用的10個(gè)單詞-p words
在目錄“ wordsx”中查找前5個(gè)最不常用的單詞,并將數(shù)字視為單詞字符,忽略大小寫,并進(jìn)行信息記錄-p wordsx -m bottom -d 1234567890 -i -n 5 -l info

有關(guān)命令行界面選項(xiàng)的更多信息,請(qǐng)參見(jiàn)自述文件中的命令行界面 。

設(shè)計(jì)

庫(kù)的設(shè)計(jì)將問(wèn)題劃分為通用并行處理實(shí)用程序,封裝用于表示原始字?jǐn)?shù)和排序字?jǐn)?shù)的數(shù)據(jù)結(jié)構(gòu)的類,最后是使用前兩組功能執(zhí)行計(jì)數(shù)和分析的類。 實(shí)際上,所有這些類都大量使用功能接口的實(shí)例,以便允許對(duì)其通用行為進(jìn)行特定的自定義。 這導(dǎo)致代碼中大量注入了lambda表達(dá)式和方法引用。 歡迎來(lái)到Java函數(shù)編程的世界!

通用并行處理實(shí)用程序

ForkJoinComputer類

ForkJoinComputer<T>類是通用的Fork / Join計(jì)算機(jī)。 它將初始大小除以2,直到達(dá)到指定的并行度或低于指定的閾值,然后使用指定的Computer<T>串行計(jì)算每個(gè)部分,然后使用指定的Merger<T>所有計(jì)算的結(jié)果。 在這里,計(jì)算機(jī)和合并是定義如下的功能接口:

public interface Computer<T> {T compute(int lo, int hi); }public interface Merger<T> {T merge(T result1, T result2); }

可以通過(guò)簡(jiǎn)單地使用適當(dāng)?shù)膌ambda實(shí)例化該類,然后調(diào)用其compute方法來(lái)使用此類。

new ForkJoinComputer<Integer>(n, 1000,(lo, hi) -> { int sum = 0; for (int i = lo + 1; i <= hi; i++) sum += i; return sum; },(a, b) -> a + b).compute();

ProducerConsumerExecutor類

ProducerConsumerExecutor<T1, T2>類是通用的Producer / Consumer執(zhí)行程序。 它啟動(dòng)一個(gè)Producer<T1>任務(wù)和多個(gè)Mediator<T1, T2>和Consumer<T2>任務(wù),它們的數(shù)量等于指定的并行度。 生產(chǎn)者將T1實(shí)例放入BlockingQueue<T1> 。 中介者從那里獲取這些實(shí)例,將其轉(zhuǎn)換為T2 ,并將其放入另一個(gè)類型為BlockingQueue<T2>阻塞隊(duì)列中。 最后,使用者從第二個(gè)阻塞隊(duì)列中獲取T2實(shí)例并對(duì)其進(jìn)行處理。

在這里, Producer, Consumer和Mediator是定義如下的功能接口:

public interface Producer<T> {void produce(Block<T> block); }public interface Consumer<T> {void consume(T t); }public interface Mediator<T1, T2> {void mediate(T1 t, Block<T2> block); }

在上面的代碼中, Block是java.util.functions定義的標(biāo)準(zhǔn)函數(shù)。 傳遞給Producer和Mediator方法的塊將產(chǎn)生的數(shù)據(jù)放入相應(yīng)的阻塞隊(duì)列中。

與ForkJoinComputer相似,可以通過(guò)簡(jiǎn)單地使用適當(dāng)?shù)膌ambda實(shí)例化該類,然后調(diào)用其execute方法來(lái)使用此類。

數(shù)據(jù)結(jié)構(gòu)類

這些類封裝了用于表示原始和已排序字?jǐn)?shù)的數(shù)據(jù)結(jié)構(gòu)。

  • WordCounts類表示映射到其用法計(jì)數(shù)的單詞列表。
  • TopWordCounts類表示映射到所有具有此類計(jì)數(shù)的單詞的單詞使用情況計(jì)數(shù)的排序列表。

字?jǐn)?shù)統(tǒng)計(jì)和分析類

WordCounter類

WordCounter類提供了一種方法,用于以串行或并行方式對(duì)表示文件或目錄樹的Path單詞進(jìn)行計(jì)數(shù)。 只需使用適當(dāng)?shù)膌ambda實(shí)例化它,然后調(diào)用其count方法即可使用它:

// Count all words consisting of only alphabetic chars, ignoring case, using parallel processing WordCounts wc = new WordCounter(path, (c) -> Character.isAlphabetic(c), (s) -> s.toLowerCase(), true).count();

并行實(shí)現(xiàn)使用ProducerConsumerExecutor<Path, String> 。 生產(chǎn)者只需遍歷目錄樹并產(chǎn)生Path實(shí)例。 中介者將文件讀入文本片段,使用者將每個(gè)文本片段中的單詞計(jì)數(shù),然后將它們收集到單個(gè)WordCounts實(shí)例中。 這是通過(guò)以下代碼完成的:

private WordCounts countPar() {final WordCounts wc = new WordCounts(parLevel);new ProducerConsumerExecutor<Path, String>((block) -> collectPaths(block),(file, block) -> readFileToBlock(file, block),(text) -> wc.add(countWords(text, pred, op)), parLevel).execute();return wc; }

WordCountAnalyzer類

WordCountAnalyzer類提供了對(duì)WordCounter產(chǎn)生的字?jǐn)?shù)進(jìn)行分析的方法,例如查找前N個(gè)最常用的字。 也可以通過(guò)簡(jiǎn)單地實(shí)例化它,然后調(diào)用它的方法之一(例如findTop或total來(lái)使用它:

// Find the top 10 most used words in wc TopWordCounts twc = new WordCountAnalyzer(wc, true).findTop(10, (x, y) -> (y - x));

Differentnet分析類型實(shí)現(xiàn)內(nèi)部Analysis<T>接口,該接口定義如下:

interface Analysis<T> {T compute(int lo, int hi);T merge(T r1, T r2); }

由于以上兩種方法的簽名模仿了ForkJoinComputer使用的Computer和Merger功能接口,因此我們可以通過(guò)以下方式對(duì)所有分析類型使用fork / join:

public TopWordCounts findTop(int number, Comparator<Integer> comparator) {return analyse(new FindTopAnalysis(number, comparator)); }private <T> T analyse(Analysis<T> a) {if (par) {return new ForkJoinComputer<T>(wc.getSize(), THRESHOLD, a::compute, a::merge, parLevel).compute();} else {return a.compute(0, wc.getSize());} }

有關(guān)庫(kù)設(shè)計(jì)的更多信息,請(qǐng)參見(jiàn)自述文件中的設(shè)計(jì)。

性能

我發(fā)現(xiàn)并行的Producer / Consumer字?jǐn)?shù)統(tǒng)計(jì)實(shí)現(xiàn)很好地適應(yīng)了不同數(shù)量的內(nèi)核和I / O速度。 它比串行實(shí)現(xiàn)要快得多。 與之不同的是,當(dāng)使用不切實(shí)際的大量唯一單詞進(jìn)行測(cè)試時(shí),并行的Fork / Join分析實(shí)現(xiàn)僅比串行的實(shí)現(xiàn)快,而且程度適中。 由于唯一字的數(shù)量很少,因此實(shí)際上比串行字慢。

下表比較了單詞計(jì)數(shù)的性能,并在以下情況下找到了最佳分析:

  • CPU AMD Phenom II X4 965 3.4 GHz(4核),4 GB RAM,Windows 7,JDK 8
  • 默認(rèn)選項(xiàng):由字母字符組成的單詞,區(qū)分大小寫
  • 默認(rèn)并行度,等于內(nèi)核數(shù)

字?jǐn)?shù)統(tǒng)計(jì)性能

實(shí)作 檔案 話 大小(MB) 時(shí)間(毫秒)
序列號(hào) 1個(gè) 10000000 ?65 2200-2400
平行 1個(gè) 10000000 ?65 500-600
序列號(hào) 100 10000000 ?65 1600-1800
平行 100 10000000 ?65 500-600

查找最佳分析性能

實(shí)作 話 最大數(shù)量 最佳 時(shí)間(毫秒)
序列號(hào) 2000000 10000000 10 200-250
平行 2000000 10000000 10 200-250

玩代碼

如果您想使用這些代碼,我建議您使用最新的NetBeans 7.3 beta,在撰寫本文時(shí)為NetBeans IDE 7.3 Beta 2 。 請(qǐng)注意,即使在此版本中,也無(wú)法在IDE中編譯lambda,因此周圍到處都有紅色標(biāo)記。 但是,從IDE啟動(dòng)Maven構(gòu)建并運(yùn)行測(cè)試仍然可以正常工作。 根據(jù)此博客文章 ,應(yīng)該可以對(duì)lambda使用IntelliJ IDEA 12 EAP內(nèi)部版本122.202或更高版本,但是我沒(méi)有親自嘗試過(guò)。 我確實(shí)嘗試了Eclipse,但由于Eclipse使用了自己的對(duì)lambda無(wú)知的JDT編譯器,因此發(fā)現(xiàn)它是一場(chǎng)失敗的比賽。

結(jié)論

這是我第一次接觸Java函數(shù)編程。 盡管Java仍然不是Scala,但是與我以前的Java代碼相比,新的函數(shù)式編程結(jié)構(gòu)大大改變了我設(shè)計(jì)和實(shí)現(xiàn)Wordcounter的方式。 我發(fā)現(xiàn)這種新的編程風(fēng)格功能強(qiáng)大且富有表現(xiàn)力,我相信隨著Java 8的發(fā)布,它將很快成為主流。

對(duì)我來(lái)說(shuō),這也是最后的“怪異敏捷”任務(wù)。 評(píng)審團(tuán)慷慨地授予了我的意見(jiàn)書,甚至在比賽結(jié)束之前,我就找到了自己的優(yōu)勝者。

如果這篇文章引起了您的興趣,請(qǐng)隨時(shí)下載并探索Wordcounter,用它來(lái)學(xué)習(xí)新的Java函數(shù)編程構(gòu)造,并讓我知道在這個(gè)過(guò)程中是否可以幫助您。

參考: Wordcounter,來(lái)自JCG合作伙伴 Stoyan Rachev的Lambdas和Fork / Join中的Java單詞計(jì)數(shù)在 Stoyan Rachev博客中。

翻譯自: https://www.javacodegeeks.com/2012/12/wordcounter-counting-words-in-java-with-lambdas-and-forkjoin.html

lambdas for

總結(jié)

以上是生活随笔為你收集整理的lambdas for_Wordcounter,使用Lambdas和Fork / Join计算Java中的单词数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。