Created
September 9, 2013 20:52
-
-
Save AnthonyMastrean/6501338 to your computer and use it in GitHub Desktop.
A comparison of unit mask converters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Behaviors] | |
public class UnitMaskConverterBehaviors | |
{ | |
It should_convert_0_to_A = () => _converter.Convert(0).ShouldEqual('A'); | |
It should_convert_1_to_B = () => _converter.Convert(1).ShouldEqual('B'); | |
It should_convert_2_to_C = () => _converter.Convert(2).ShouldEqual('C'); | |
It should_convert_4_to_D = () => _converter.Convert(4).ShouldEqual('D'); | |
It should_convert_8_to_E = () => _converter.Convert(8).ShouldEqual('E'); | |
It should_convert_16_to_F = () => _converter.Convert(16).ShouldEqual('F'); | |
It should_convert_32_to_G = () => _converter.Convert(32).ShouldEqual('G'); | |
It should_convert_64_to_H = () => _converter.Convert(64).ShouldEqual('H'); | |
It should_convert_128_to_I = () => _converter.Convert(128).ShouldEqual('I'); | |
It should_convert_256_to_J = () => _converter.Convert(256).ShouldEqual('J'); | |
It should_convert_512_to_K = () => _converter.Convert(512).ShouldEqual('K'); | |
It should_convert_1024_to_L = () => _converter.Convert(1024).ShouldEqual('L'); | |
It should_convert_2048_to_M = () => _converter.Convert(2048).ShouldEqual('M'); | |
It should_convert_4096_to_N = () => _converter.Convert(4096).ShouldEqual('N'); | |
It should_convert_8192_to_O = () => _converter.Convert(8192).ShouldEqual('O'); | |
It should_convert_16384_to_P = () => _converter.Convert(16384).ShouldEqual('P'); | |
It should_convert_32768_to_Q = () => _converter.Convert(32768).ShouldEqual('Q'); | |
It should_convert_65536_to_R = () => _converter.Convert(65536).ShouldEqual('R'); | |
It should_convert_131072_to_S = () => _converter.Convert(131072).ShouldEqual('S'); | |
It should_convert_262144_to_T = () => _converter.Convert(262144).ShouldEqual('T'); | |
It should_convert_524288_to_U = () => _converter.Convert(524288).ShouldEqual('U'); | |
It should_convert_1048576_to_V = () => _converter.Convert(1048576).ShouldEqual('V'); | |
It should_convert_2097152_to_W = () => _converter.Convert(2097152).ShouldEqual('W'); | |
It should_convert_4194304_to_X = () => _converter.Convert(4194304).ShouldEqual('X'); | |
It should_convert_8388608_to_Y = () => _converter.Convert(8388608).ShouldEqual('Y'); | |
It should_convert_16777216_to_Z = () => _converter.Convert(16777216).ShouldEqual('Z'); | |
protected static IUnitMaskConverter _converter; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Behaviors] | |
public class UnitMaskPerformanceBehaviors | |
{ | |
It should_take_less_than_one_millisecond_per_iteration = () => | |
{ | |
const double n = 10000000.0; | |
var stopwatch = Stopwatch.StartNew(); | |
for (var count = 0; count <= n; count++) | |
{ | |
var result = _converter.Convert(16777216); | |
} | |
stopwatch.Stop(); | |
var iteration = stopwatch.ElapsedMilliseconds / n; | |
// Prints a message like this | |
// [WhateverUnitMaskConverter]: 10000000 iterations in 498 ms (0.000049800 ms/iteration) | |
Debug.Print("[{0}]: {1} iterations in {2} ms ({3:F9} ms/iteration)", _converter.GetType().Name, n, stopwatch.ElapsedMilliseconds, iteration); | |
iteration.ShouldBeLessThan(1); | |
}; | |
protected static IUnitMaskConverter _converter; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BinaryUnitMaskConverter : IUnitMaskConverter | |
{ | |
public char Convert(uint mask) | |
{ | |
var result = System.Convert.ToString(mask, 2); | |
return result.Contains("1") | |
? (char)(result.Substring(result.IndexOf('1')).Length + 65) | |
: 'A'; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class LogUnitMaskConverter : IUnitMaskConverter | |
{ | |
public char Convert(uint mask) | |
{ | |
var result = Math.Log(mask, 2.0); | |
return result != double.NegativeInfinity | |
? (char)(result + 66) | |
: 'A'; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class LookupUnitMaskConverter : IUnitMaskConverter | |
{ | |
private static readonly Dictionary<uint, char> map = new Dictionary<uint, char> | |
{ | |
{ 0 , 'A' }, | |
{ 1 , 'B' }, | |
{ 2 , 'C' }, | |
{ 4 , 'D' }, | |
{ 8 , 'E' }, | |
{ 16 , 'F' }, | |
{ 32 , 'G' }, | |
{ 64 , 'H' }, | |
{ 128 , 'I' }, | |
{ 256 , 'J' }, | |
{ 512 , 'K' }, | |
{ 1024 , 'L' }, | |
{ 2048 , 'M' }, | |
{ 4096 , 'N' }, | |
{ 8192 , 'O' }, | |
{ 16384 , 'P' }, | |
{ 32768 , 'Q' }, | |
{ 65536 , 'R' }, | |
{ 131072 , 'S' }, | |
{ 262144 , 'T' }, | |
{ 524288 , 'U' }, | |
{ 1048576 , 'V' }, | |
{ 2097152 , 'W' }, | |
{ 4194304 , 'X' }, | |
{ 8388608 , 'Y' }, | |
{ 16777216, 'Z' }, | |
}; | |
public char Convert(uint mask) | |
{ | |
return map[mask]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class OriginalUnitMaskConverter : IUnitMaskConverter | |
{ | |
private static readonly char[] Units = new[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; | |
public char Convert(uint mask) | |
{ | |
var index = 0; | |
var array = new BitArray(BitConverter.GetBytes(mask)); | |
foreach (bool var in array) | |
{ | |
if (var) | |
break; | |
index++; | |
} | |
return Units[index]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IUnitMaskConverter | |
{ | |
char Convert(uint mask); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Subject(typeof(IUnitMaskConverter))] | |
public class When_converting_unit_masks_by_original_method | |
{ | |
Behaves_like<UnitMaskConverterBehaviors> a_unit_mask_converter; | |
Behaves_like<UnitMaskPerformanceBehaviors> a_high_performance_converter; | |
protected static OriginalUnitMaskConverter _converter = new OriginalUnitMaskConverter(); | |
} | |
[Subject(typeof(IUnitMaskConverter))] | |
public class When_converting_unit_masks_by_lookup | |
{ | |
Behaves_like<UnitMaskConverterBehaviors> a_unit_mask_converter; | |
Behaves_like<UnitMaskPerformanceBehaviors> a_high_performance_converter; | |
protected static LookupUnitMaskConverter _converter = new LookupUnitMaskConverter(); | |
} | |
[Subject(typeof(IUnitMaskConverter))] | |
public class When_converting_unit_masks_by_log | |
{ | |
Behaves_like<UnitMaskConverterBehaviors> a_unit_mask_converter; | |
Behaves_like<UnitMaskPerformanceBehaviors> a_high_performance_converter; | |
protected static LogUnitMaskConverter _converter = new LogUnitMaskConverter(); | |
} | |
[Subject(typeof(IUnitMaskConverter))] | |
public class When_converting_unit_masks_by_binary | |
{ | |
Behaves_like<UnitMaskConverterBehaviors> a_unit_mask_converter; | |
Behaves_like<UnitMaskPerformanceBehaviors> a_high_performance_converter; | |
protected static BinaryUnitMaskConverter _converter = new BinaryUnitMaskConverter(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment