Распределение задачи по ядрам - 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; }
}