亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

統計大文件里,頻率最高的10個單詞,(C# TPL DataFlow版)

2019-11-17 02:26:24
字體:
來源:轉載
供稿:網友

統計大文件里,頻率最高的10個單詞,(C# TPL DataFlow版)

最近公司搞了一個寫程序的比賽,要求從2G的文件里統計出出現頻率最高的10個單詞。

最開始的想法是使用字典樹,后來發現字典樹更適合用在找前綴上,在查找沒有hash表效率高。

之后使用Hash表+DataFlow完成了功能,2G的文件處理在20秒以內(其實我有信心優化到10秒以內,但是太折騰了)。

這是我的設計圖:

為什么要形成那么多結果?因為我不想寫鎖,寫鎖會降低很多效率,而且也失去了線程的意義,每個線程做自己的工作,

最后在把每個線程處理的結果匯總起來,這樣也符合fork join 的設計。

而且我也試過,如果寫鎖的話,效率會降低10秒以上,我也嘗試過微軟提供的ConcurrentDictionary 原子哈希表,但是效果都不是

很理想,而且,在并行的年代,在寫鎖這個東西,感覺很惡心,好像在代碼里加了一坨屎一樣,我以前就很討厭鎖,也出現過代碼死鎖的情況。

最后我選擇了使用微軟的TPL 庫來解決并行的問題。

使用DataFlow解決了我處理時多線程管理的問題,還有線程等待消息隊列的問題,

使用BufferBlock 進行主控與工作線程之間消息傳遞,這是我的設計圖:

讀取文件之后使用BufferBlock.Post發送給工作線程,工作線程使用TryReceive接收消息,并且處理。

在MSDNhttps://msdn.microsoft.com/zh-cn/library/hh228601(v=vs.110).aspx 里有詳細的介紹。

這是典型的單生產者,多使用者的列子。

代碼方面首先是讀取文件:

  public class FileBufferBlock    {               PRivate string _fileName;        BufferBlock<WordStream> _buffer = null;        public FileBufferBlock(BufferBlock<WordStream> buffer,string fileName)        {            this._fileName = fileName;            this._buffer = buffer;        }        /// <summary>        /// 按32M讀取文件,循環發送給WordBufferBlock        /// </summary>        public void ReadFile()        {            using (FileStream fs = new FileStream(_fileName, FileMode.Open, Fileaccess.Read))            {                using (StreamReader sr = new StreamReader(fs))                {                    while (!sr.EndOfStream)                    {                        char[] charBuffer = new char[32 * 1024 * 1024];                        sr.ReadBlock(charBuffer, 0, charBuffer.Length);                        _buffer.Post(new WordStream(charBuffer));                    }                }            }            _buffer.Complete();        }

在這里使用BufferBlock.Post 發送消息給工作線程,如果不用它,你得去找個能阻塞的消息隊列。

下面是我的接收方的代碼,使用BufferBlock.TryReceive 接收消息,然后處理,在這里可以開多個個線程去處理。

而且線程是它幫你管理的:

// --------------------------------------------------------------------------------------------------------------------// <copyright file="WordProcessBufferBlock.cs" company="yada">//   Copyright (c) yada Corporation. All rights reserved.// </copyright>// change by qugang 2015.4.18// 描述:用于截取單詞的工作線程// --------------------------------------------------------------------------------------------------------------------using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Threading.Tasks.Dataflow;namespace WordStatistics{    public class WordProcessBufferBlock    {        private int _taskCount = 1;        BufferBlock<WordStream> _buffer = null;        private List<Task<Dictionary<string, int>>> _list = new List<Task<Dictionary<string, int>>>();        /// <summary>        /// 單詞處理類        /// </summary>        /// <param name="taskCount">工作線程數</param>        /// <param name="buffer">DataFlow的BufferBlock</param>        public WordProcessBufferBlock(int taskCount, BufferBlock<WordStream> buffer)        {            _taskCount = taskCount;            this._buffer = buffer;        }        public void StartWord()        {            for (int i = 0; i < _taskCount; i++)            {                _list.Add(Process());            }        }        /// <summary>        /// 等待所有工作完成        /// </summary>        /// <param name="f">完成后的工作函數</param>        public void WaitAll(Action<Dictionary<string,int>> f)        {            Task.WaitAll(_list.ToArray());            foreach (var row in _list)            {                f(row.Result);            }        }        /// <summary>        /// 使用BufferBlock.TryReceive循環從消息里取從FileBufferBlock發送的buffer        /// </summary>        /// <returns>工作結果</returns>        private async Task<Dictionary<string, int>> Process()        {            Dictionary<string, int> dic = new Dictionary<string, int>();            while (await _buffer.OutputAvailableAsync())            {                WordStream ws;                while (_buffer.TryReceive(out ws))                {                    foreach (string value in ws)                    {                        if (dic.ContainsKey(value))                        {                            dic[value]++;                        }                        else                        {                            dic.Add(value, 1);                        }                    }                }            }            return dic;        }    }}

WordStrem是我自己寫的一個單詞枚舉流,繼承了IEnumerable接口,將找單詞的算法寫到枚舉器里面,實現流化。

// --------------------------------------------------------------------------------------------------------------------// <copyright file="WordStatistics.cs" company="yada">//   Copyright (c) yada Corporation. All rights reserved.// </copyright>// change by qugang 2015.4.18// 單詞枚舉器:算法從開始找字母,如果不是字母,則返回從pos 到end 的組成單詞// --------------------------------------------------------------------------------------------------------------------using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace WordStatistics{    /// <summary>    /// 單詞枚舉器    /// </summary>    public class WordStream : IEnumerable    {        private char[] buffer;        public WordStream(char[] buffer)        {            this.buffer = buffer;        }        IEnumerator IEnumerable.GetEnumerator()        {            return (IEnumerator)GetEnumerator();        }        public WordStreamEnum GetEnumerator()        {            return new WordStreamEnum(this.buffer);        }    }    public class WordStreamEnum : IEnumerator    {        private char[] buffer;        int pos = 0;        int endCount = 0;        int index = -1;        public WordStreamEnum(char[] buffer)        {            this.buffer = buffer;        }        public bool MoveNext()        {            while (index < buffer.Length - 1)            {                index++;                char buff = buffer[index];                if ((buff >= 'a' && buff <= 'z') || (buff >= 'A' && buff <= 'Z'))                {                    if (endCount == 0)                    {                        pos = index;                        endCount++;                    }                    else                    {                        endCount++;                    }                }                else                {                    if (endCount != 0)                        return true;                }                if (buff == '/0')                {                    return false;                }            }            return false;        }        public object Current        {            get            {                int tempInt = endCount;                endCount = 0;                return new string(buffer, pos, tempInt);            }        }        public void Reset()        {            index = -1;        }    }}

到這里就完成了,然后再Main函數里添加調用

  static void Main(string[] args)        {            DateTime dt = DateTime.Now;            var buffer = new BufferBlock<WordStream>();            //創建工作BufferBlock            WordProcessBufferBlock wb = new WordProcessBufferBlock(8, buffer);            wb.StartWord();            //創建讀取文件,發送的BufferBlock            FileBufferBlock fb = new FileBufferBlock(buffer, @"D:/content.txt");            fb.ReadFile();            Dictionary<string,int> dic = new Dictionary<string,int>();            //等待工作完成匯總結果            wb.WaitAll(p =>                {                    foreach (var row in p)                    {                        if (!dic.ContainsKey(row.Key))                            dic.Add(row.Key, row.Value);                        else                        {                            dic[row.K
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
九九九久久国产免费| 久热国产精品视频| 亚洲欧美日韩精品| 久久免费国产视频| 91最新国产视频| 亚洲成色777777女色窝| 91免费在线视频网站| 日韩中文字幕在线免费观看| 日韩在线小视频| 欧美激情在线视频二区| 国产日本欧美一区二区三区在线| 久久影视三级福利片| 亚洲欧美一区二区三区情侣bbw| 久久精品中文字幕电影| 亚洲综合在线播放| 亚洲精品影视在线观看| 亚洲综合在线中文字幕| 久久久久久国产精品久久| 69国产精品成人在线播放| 久久久久久久电影一区| 97视频在线观看视频免费视频| 日日摸夜夜添一区| 欧美成人免费一级人片100| 人妖精品videosex性欧美| 国产一区二区三区丝袜| 日韩av电影手机在线| 国产精品美女午夜av| 青青草原成人在线视频| 国产一区二区精品丝袜| 日日骚久久av| 欧洲永久精品大片ww免费漫画| 亚洲丝袜av一区| 国产亚洲精品日韩| 亚洲精品自在久久| 欧美福利小视频| 成人国内精品久久久久一区| 亚洲精品第一页| 亚洲精品成人免费| 欧美精品激情在线观看| 久久国产精品久久国产精品| 久久久久久97| 国产一区二区三区久久精品| 日韩高清av在线| 亚洲小视频在线观看| 欧美电影在线播放| 欧美在线观看一区二区三区| 国产日韩欧美夫妻视频在线观看| 国产精品久久久久久久电影| 日韩av网站导航| 日本成人在线视频网址| 夜夜嗨av一区二区三区四区| 国产亚洲精品久久久久久牛牛| 国产亚洲精品久久久久久牛牛| 91老司机精品视频| 庆余年2免费日韩剧观看大牛| 欧美视频不卡中文| 国产一区视频在线播放| 不卡伊人av在线播放| 欧美性生交大片免费| 国产精品久久久久久久久久尿| 国产精品美乳一区二区免费| 久久久www成人免费精品张筱雨| 91精品国产色综合久久不卡98| 亚洲一区亚洲二区亚洲三区| 欧美日韩加勒比精品一区| 亚洲自拍偷拍第一页| 国产欧美一区二区三区在线看| 国产性色av一区二区| 日韩av网站在线| 96精品久久久久中文字幕| 国产亚洲欧洲高清| 亚洲视频电影图片偷拍一区| 日韩成人在线免费观看| 色天天综合狠狠色| 午夜精品久久久久久久99黑人| 大胆欧美人体视频| 日本电影亚洲天堂| 国产ts人妖一区二区三区| 国产免费一区二区三区在线观看| 热久久视久久精品18亚洲精品| 国产精品日韩精品| 国产精品欧美激情在线播放| 欧美国产一区二区三区| 欧美日韩国产影院| 日韩激情视频在线播放| 国产在线视频91| 亚洲成人网在线观看| 国产欧美 在线欧美| 久久久噜久噜久久综合| 中文字幕亚洲综合久久| 久久精品影视伊人网| 中文字幕在线成人| 国产亚洲精品美女久久久久| 成人免费淫片aa视频免费| 国产日韩欧美影视| 亚洲成人av中文字幕| 亚洲国产成人爱av在线播放| 国产一区私人高清影院| 亚洲直播在线一区| 国产视频精品一区二区三区| 国产丝袜一区二区| 性色av一区二区三区在线观看| 日韩精品视频免费在线观看| 日韩av在线电影网| 欧美日本高清一区| 中文字幕亚洲欧美在线| 精品久久久久久中文字幕大豆网| 日韩电影中文字幕在线观看| 成人午夜一级二级三级| 国产精品久久久久久久久久久久| 亚洲第一天堂av| 欧美噜噜久久久xxx| 久久综合伊人77777蜜臀| 一道本无吗dⅴd在线播放一区| 国产一区二区久久精品| 久久精品国产欧美亚洲人人爽| 青青青国产精品一区二区| 国产91在线播放| 久久免费视频在线观看| 国产91精品黑色丝袜高跟鞋| 久久亚洲欧美日韩精品专区| 欧美电影免费在线观看| 91系列在线观看| 九九热这里只有精品免费看| 在线播放国产精品| 色偷偷综合社区| 精品国内亚洲在观看18黄| 精品爽片免费看久久| 欧美色播在线播放| 国产伊人精品在线| 亚洲福利小视频| 亚洲国产又黄又爽女人高潮的| 992tv成人免费视频| 成人av电影天堂| 国产亚洲综合久久| 超薄丝袜一区二区| 欧美最顶级丰满的aⅴ艳星| 成人网中文字幕| 国产精品va在线| 92版电视剧仙鹤神针在线观看| 97超级碰在线看视频免费在线看| 久久精品国产99国产精品澳门| 亚洲天堂免费视频| 久久视频在线免费观看| 91精品国产自产在线老师啪| 国产精品18久久久久久首页狼| 一级做a爰片久久毛片美女图片| 91精品国产高清自在线看超| 欧美日韩激情视频| wwwwwwww亚洲| 色综合久综合久久综合久鬼88| 日韩在线视频一区| 这里只有精品视频| 成人久久精品视频| 精品国产一区二区三区久久久狼| 欧美极品欧美精品欧美视频| 国产精品入口免费视频一| 亚洲韩国青草视频| 亚洲国内精品视频| 国产日韩在线一区| 日韩成人激情在线| 国产精品亚洲片夜色在线| 久久天天躁狠狠躁夜夜躁2014| 国产精品女人网站|