Распределение задачи по ядрам - C#
Формулировка задачи:
Собственно есть большой файл (около 16 тысяч строк). Путем проверки лога было установлено, что проблема в сортировке. Сортировал пузырьком, однако это крайне медленно. Пытался распараллелить с помощью Parallel. В итоге получаю не отсортированный массив. Как увеличить быстродействие?
Решение задачи: «Распределение задачи по ядрам»
textual
Листинг программы
private void button1_Click(object sender, EventArgs e) { openFileDialog1.InitialDirectory = Application.StartupPath + @"\Data\"; openFileDialog1.Filter = @"txt files (*.txt)|*.txt"; openFileDialog1.FilterIndex = 1; openFileDialog1.RestoreDirectory = true; if (openFileDialog1.ShowDialog() != DialogResult.OK) return; var npcPath = Application.StartupPath + @"\Data\npcdata.txt"; var clearSpawnPath = Application.StartupPath + @"\Data\clear_spawn.txt"; Parse(openFileDialog1.FileName, npcPath, clearSpawnPath); } private void Parse(string spawnPath, string npcPath, string clearSpawnPath) { richTextBox1.Clear(); richTextBox1.AppendText(DateTime.Now + " Loading npcdata.txt..."); if (!File.Exists(npcPath)) { MessageBox.Show(string.Format(@"Error! File {0} does not exist.", Path.GetFileName(spawnPath))); return; } var npcData = ParseNpcData(npcPath); richTextBox1.AppendText("\n" + DateTime.Now + " Loading spawn file..."); var spawnData = ParseSpawnData(spawnPath); richTextBox1.AppendText("\n" + DateTime.Now + " Saving file spawn..."); using (var stream = new StreamWriter(new FileStream(clearSpawnPath, FileMode.Create), Encoding.ASCII)) { foreach (var spawnInfo in spawnData) { if (spawnInfo.Id < 20000) continue; var id = npcData.ContainsKey(spawnInfo.Id) ? npcData[spawnInfo.Id] : spawnInfo.Id.ToString(); stream.WriteLine("{0}\t{1}\t{2}\t{3}", id, spawnInfo.X, spawnInfo.Y, spawnInfo.Z); } } richTextBox1.AppendText("\n" + DateTime.Now + " Complete!"); } private static Dictionary<int, string> ParseNpcData(string npcPath) { var npcRegex = new Regex(@"^\w+\s\w+\s(?<id>\d+)\s\[(?<name>\w+)\]$", RegexOptions.Compiled); var npcData = new Dictionary<int, string>(); using (var stream = new StreamReader(npcPath, Encoding.Default)) { string line; while ((line = stream.ReadLine()) != null) { var match = npcRegex.Match(line); if (!match.Success) continue; var id = int.Parse(match.Groups["id"].Value); var name = match.Groups["name"].Value; if (!npcData.ContainsKey(id)) npcData.Add(id, name); } } return npcData; } private static List<SpawnInfo> ParseSpawnData(string spawnPath) { var spawnRegex = new Regex(@"^\d\d(?<id>\d+)\s\d+\s(?<x>\d+)\s(?<y>\d+)\s(?<z>\-\d+)\s\d+$", RegexOptions.Compiled); var spawnData = new List<SpawnInfo>(); using (var stream = new StreamReader(spawnPath, Encoding.Default)) { string line; while ((line = stream.ReadLine()) != null) { var match = spawnRegex.Match(line); if (!match.Success) continue; var id = int.Parse(match.Groups["id"].Value); var x = int.Parse(match.Groups["x"].Value); var y = int.Parse(match.Groups["y"].Value); var z = int.Parse(match.Groups["z"].Value); spawnData.Add(new SpawnInfo(id, x, y, z)); } } return spawnData.Distinct().AsParallel() .OrderBy(spawn => spawn.Id) .ThenBy(spawn => spawn.X) .ThenBy(spawn => spawn.Y) .ThenBy(spawn => spawn.Z) .ToList(); } private struct SpawnInfo { public SpawnInfo(int id, int x, int y, int z) : this() { Id = id; X = x; Y = y; Z = z; } public int Id { get; private set; } public int X { get; private set; } public int Y { get; private set; } public int Z { get; private set; } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д