Skip to content

Instantly share code, notes, and snippets.

@gravejester
Last active April 9, 2017 12:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gravejester/6c9a1bdd12ba413590c9 to your computer and use it in GitHub Desktop.
Save gravejester/6c9a1bdd12ba413590c9 to your computer and use it in GitHub Desktop.
param([Parameter(Position = 0)][string] $Path = 'C:\Users\grave\Downloads\ChessData-master\')
$code = @{
Name = 'ResultCounter'
Namespace = 'ChessData'
PassThru = $true
UsingNamespace = @(
'System.Collections.Concurrent',
'System.IO',
'System.Threading.Tasks'
)
MemberDefinition = @'
public static ConcurrentDictionary<string, int> ProcessChessFiles(string path)
{
ConcurrentDictionary<string, int> result = new ConcurrentDictionary<string, int>();
string tie = "1/2-1/2";
string black = "0-1";
string white = "1-0";
string lineResult = "[Result";
Parallel.ForEach<string>(Directory.EnumerateFiles(path, "*.pgn", SearchOption.AllDirectories), filename =>
{
using (StreamReader sr = new StreamReader(filename))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if ((line.Length - line.Replace(lineResult, String.Empty).Length) / lineResult.Length == 1)
{
if ((line.Length - line.Replace(white, String.Empty).Length) / white.Length == 1)
{
result.AddOrUpdate("White", 1, (k, v) => v + 1);
}
else if ((line.Length - line.Replace(tie, String.Empty).Length) / tie.Length == 1)
{
result.AddOrUpdate("Tie", 1, (k, v) => v + 1);
}
else if ((line.Length - line.Replace(black, String.Empty).Length) / black.Length == 1)
{
result.AddOrUpdate("Black", 1, (k, v) => v + 1);
}
}
}
}
});
return result;
}
'@
}
$CompilerParams = [System.CodeDom.Compiler.CompilerParameters]::new()
$CompilerParams.CompilerOptions = "/optimize+ /warn:0"
$class = Add-Type @code -CompilerParameters $CompilerParams |Select-Object -First 1
Measure-Command {
$res = $class::ProcessChessFiles($Path)
}
$res | Format-Table
@gravejester
Copy link
Author

I tried several iterations of compiled code, only to come to the conclusion that Mathias (@IISResetMe)
had a close to perfect implementation (as far as I could tell). So I decided to take his code and
shave a couple of extra seconds from it, and I think I succeeded.

My notable changes are:

  • skipped converting ConcurrentDictionary to HashTable
  • replaced his string matching to a more efficient one
  • skipped logic to only add the custom class if it was not already loaded
  • skipped the internal Measure-Command
  • fixed it so that it counts correctly ;)

Hope you don't mind Mathias :)

@gravejester
Copy link
Author

Added the internal Measure-Command back in :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment