Last think I should embark on whilest under the influence of a sleeping pill is something like this, never mind sober, but I couldn't stop myself.
It's been a long time since I did any C# so I said "Time to re-hone those atrophying skills", ergo an attempt here.
I went the easy way of buffered binary read, thinking it would be faster (since we're ultimately dealing with binary data why convert to and from), and more bomb proof on large files.
Processes a 50 MB file pretty fast, maybe 1 second?
Anyway, sewerage --
using System;
using System.IO;
namespace Thetan
{
class Program
{
private const int BUFFER_SIZE = 8192;
private static long[] IndexBytes( string filename )
{
// caller's responsibility to
// pass a valid, readable file
long[] result = new long[ 256 ];
// use buffered binary read. Should be fast
// and won't chuck a wobbly on big files
Stream inputStream = File.OpenRead( filename );
BufferedStream bufferedStream = new BufferedStream( inputStream );
byte[] buffer = new byte[ BUFFER_SIZE ];
int bytesRead;
while ( ( bytesRead = bufferedStream.Read( buffer, 0, BUFFER_SIZE )) > 0 )
for ( int i = 0 ; i < bytesRead ; i++ )
result[ buffer[ i ] ]++;
bufferedStream.Close();
return result;
} //------------------------------------------------------------
static void Main(string[] args)
{
// This file example file is about 53 MB.
string filename = @"C:\Docs\Downloads\iTunesSetup.exe";
if ( File.Exists( filename ) )
{
long[] results = IndexBytes( filename);
ShowResults ( results, false );
}
} //------------------------------------------------------------
private static void ShowResults ( long[] results, bool toUpper )
{
if ( toUpper ) // force upper case registers
// to represent lower + upper
{
for ( int i = 65, k = 97 ; i < 91 ; i++, k++ )
{
results[i] += results[k];
results[k] = 0;
}
}
Console.WriteLine( "Talley" );
Console.WriteLine( "=============" );
ShowRange ( results, 48, 58 );
if ( !toUpper ) ShowRange ( results, 97, 123 );
ShowRange ( results, 65, 91 );
Console.WriteLine( "\nPress [Enter] to continue" );
Console.ReadLine();
} //------------------------------------------------------------
private static void ShowRange ( long[] results, int startIndex, int endIndex )
{
for ( int i = startIndex ; i < endIndex ; i++ )
{
Console.WriteLine( "{0}'s => {1}", (char)i, results[i] );
}
}
}
}
Looks verbose but I'm guessing it performs well against the other versions (tho I never benched anything myself).