Last active
August 18, 2022 13:16
-
-
Save bartoszkp/9e059c3edccc07a5e588 to your computer and use it in GitHub Desktop.
Enum.GetValues: cast vs. no cast to typed array test.
This file contains 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
// Intel(R) Core(TM) i7-2600 CPU @ 3.40 GHz 3.40 GHz | |
// 16 GB RAM, Windows 7, 64 bit | |
// | |
//No cast:0.854751600000001 +- 0.182965645566156ms | |
//Cast:0.724137 +- 0.148216330378943ms | |
// Conclusion: Cast is indeed faster, but remember that we are talking here about _miliseconds_ | |
// for 1000 enumerations of an enum with 1000 elements. First verify whether this is really significant in your code, before | |
// proceeding with micro-optimizations. | |
// Context: http://stackoverflow.com/a/105402/2642204 | |
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
namespace EnumTest | |
{ | |
public class Program | |
{ | |
enum E | |
{ | |
V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30, V31, V32, | |
V33, V34, V35, V36, V37, V38, V39, V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, V50, V51, V52, V53, V54, V55, V56, V57, V58, V59, V60, V61, V62, | |
V63, V64, V65, V66, V67, V68, V69, V70, V71, V72, V73, V74, V75, V76, V77, V78, V79, V80, V81, V82, V83, V84, V85, V86, V87, V88, V89, V90, V91, V92, | |
V93, V94, V95, V96, V97, V98, V99, V100, V101, V102, V103, V104, V105, V106, V107, V108, V109, V110, V111, V112, V113, V114, V115, V116, V117, V118, | |
V119, V120, V121, V122, V123, V124, V125, V126, V127, V128, V129, V130, V131, V132, V133, V134, V135, V136, V137, V138, V139, V140, V141, V142, V143, | |
V144, V145, V146, V147, V148, V149, V150, V151, V152, V153, V154, V155, V156, V157, V158, V159, V160, V161, V162, V163, V164, V165, V166, V167, V168, | |
V169, V170, V171, V172, V173, V174, V175, V176, V177, V178, V179, V180, V181, V182, V183, V184, V185, V186, V187, V188, V189, V190, V191, V192, V193, | |
V194, V195, V196, V197, V198, V199, V200, V201, V202, V203, V204, V205, V206, V207, V208, V209, V210, V211, V212, V213, V214, V215, V216, V217, V218, | |
V219, V220, V221, V222, V223, V224, V225, V226, V227, V228, V229, V230, V231, V232, V233, V234, V235, V236, V237, V238, V239, V240, V241, V242, V243, | |
V244, V245, V246, V247, V248, V249, V250, V251, V252, V253, V254, V255, V256, V257, V258, V259, V260, V261, V262, V263, V264, V265, V266, V267, V268, | |
V269, V270, V271, V272, V273, V274, V275, V276, V277, V278, V279, V280, V281, V282, V283, V284, V285, V286, V287, V288, V289, V290, V291, V292, V293, | |
V294, V295, V296, V297, V298, V299, V300, V301, V302, V303, V304, V305, V306, V307, V308, V309, V310, V311, V312, V313, V314, V315, V316, V317, V318, | |
V319, V320, V321, V322, V323, V324, V325, V326, V327, V328, V329, V330, V331, V332, V333, V334, V335, V336, V337, V338, V339, V340, V341, V342, V343, | |
V344, V345, V346, V347, V348, V349, V350, V351, V352, V353, V354, V355, V356, V357, V358, V359, V360, V361, V362, V363, V364, V365, V366, V367, V368, | |
V369, V370, V371, V372, V373, V374, V375, V376, V377, V378, V379, V380, V381, V382, V383, V384, V385, V386, V387, V388, V389, V390, V391, V392, V393, | |
V394, V395, V396, V397, V398, V399, V400, V401, V402, V403, V404, V405, V406, V407, V408, V409, V410, V411, V412, V413, V414, V415, V416, V417, V418, | |
V419, V420, V421, V422, V423, V424, V425, V426, V427, V428, V429, V430, V431, V432, V433, V434, V435, V436, V437, V438, V439, V440, V441, V442, V443, | |
V444, V445, V446, V447, V448, V449, V450, V451, V452, V453, V454, V455, V456, V457, V458, V459, V460, V461, V462, V463, V464, V465, V466, V467, V468, | |
V469, V470, V471, V472, V473, V474, V475, V476, V477, V478, V479, V480, V481, V482, V483, V484, V485, V486, V487, V488, V489, V490, V491, V492, V493, | |
V494, V495, V496, V497, V498, V499, V500, V501, V502, V503, V504, V505, V506, V507, V508, V509, V510, V511, V512, V513, V514, V515, V516, V517, V518, | |
V519, V520, V521, V522, V523, V524, V525, V526, V527, V528, V529, V530, V531, V532, V533, V534, V535, V536, V537, V538, V539, V540, V541, V542, V543, | |
V544, V545, V546, V547, V548, V549, V550, V551, V552, V553, V554, V555, V556, V557, V558, V559, V560, V561, V562, V563, V564, V565, V566, V567, V568, | |
V569, V570, V571, V572, V573, V574, V575, V576, V577, V578, V579, V580, V581, V582, V583, V584, V585, V586, V587, V588, V589, V590, V591, V592, V593, | |
V594, V595, V596, V597, V598, V599, V600, V601, V602, V603, V604, V605, V606, V607, V608, V609, V610, V611, V612, V613, V614, V615, V616, V617, V618, | |
V619, V620, V621, V622, V623, V624, V625, V626, V627, V628, V629, V630, V631, V632, V633, V634, V635, V636, V637, V638, V639, V640, V641, V642, V643, | |
V644, V645, V646, V647, V648, V649, V650, V651, V652, V653, V654, V655, V656, V657, V658, V659, V660, V661, V662, V663, V664, V665, V666, V667, V668, | |
V669, V670, V671, V672, V673, V674, V675, V676, V677, V678, V679, V680, V681, V682, V683, V684, V685, V686, V687, V688, V689, V690, V691, V692, V693, | |
V694, V695, V696, V697, V698, V699, V700, V701, V702, V703, V704, V705, V706, V707, V708, V709, V710, V711, V712, V713, V714, V715, V716, V717, V718, | |
V719, V720, V721, V722, V723, V724, V725, V726, V727, V728, V729, V730, V731, V732, V733, V734, V735, V736, V737, V738, V739, V740, V741, V742, V743, | |
V744, V745, V746, V747, V748, V749, V750, V751, V752, V753, V754, V755, V756, V757, V758, V759, V760, V761, V762, V763, V764, V765, V766, V767, V768, | |
V769, V770, V771, V772, V773, V774, V775, V776, V777, V778, V779, V780, V781, V782, V783, V784, V785, V786, V787, V788, V789, V790, V791, V792, V793, | |
V794, V795, V796, V797, V798, V799, V800, V801, V802, V803, V804, V805, V806, V807, V808, V809, V810, V811, V812, V813, V814, V815, V816, V817, V818, | |
V819, V820, V821, V822, V823, V824, V825, V826, V827, V828, V829, V830, V831, V832, V833, V834, V835, V836, V837, V838, V839, V840, V841, V842, V843, | |
V844, V845, V846, V847, V848, V849, V850, V851, V852, V853, V854, V855, V856, V857, V858, V859, V860, V861, V862, V863, V864, V865, V866, V867, V868, | |
V869, V870, V871, V872, V873, V874, V875, V876, V877, V878, V879, V880, V881, V882, V883, V884, V885, V886, V887, V888, V889, V890, V891, V892, V893, | |
V894, V895, V896, V897, V898, V899, V900, V901, V902, V903, V904, V905, V906, V907, V908, V909, V910, V911, V912, V913, V914, V915, V916, V917, V918, | |
V919, V920, V921, V922, V923, V924, V925, V926, V927, V928, V929, V930, V931, V932, V933, V934, V935, V936, V937, V938, V939, V940, V941, V942, V943, | |
V944, V945, V946, V947, V948, V949, V950, V951, V952, V953, V954, V955, V956, V957, V958, V959, V960, V961, V962, V963, V964, V965, V966, V967, V968, | |
V969, V970, V971, V972, V973, V974, V975, V976, V977, V978, V979, V980, V981, V982, V983, V984, V985, V986, V987, V988, V989, V990, V991, V992, V993, | |
V994, V995, V996, V997, V998, V999, V1000 | |
} | |
static void Main(string[] args) | |
{ | |
const int IterationCount = 1000; | |
Warmup(IterationCount); | |
Action noCastCall = () => TestNoCast(); | |
Action castCall = () => TestCast(); | |
Stopwatch sw = new Stopwatch(); | |
var noCast = Enumerable | |
.Range(0, IterationCount) | |
.Select(i => Measure(sw, noCastCall)) | |
.ToArray(); | |
var cast = Enumerable | |
.Range(0, IterationCount) | |
.Select(i => Measure(sw, castCall)) | |
.ToArray(); | |
var noCastAvg = Average(noCast); | |
var castAvg = Average(cast); | |
var noCastStdDev = StandardDeviation(noCastAvg, noCast); | |
var castStdDev = StandardDeviation(castAvg, cast); | |
Console.WriteLine("No cast:" + noCastAvg + " +- " + noCastStdDev + "ms"); | |
Console.WriteLine("Cast:" + castAvg + " +- " + castStdDev + "ms"); | |
Console.ReadKey(); | |
} | |
static void Warmup(int iterationCount) | |
{ | |
foreach (var x in Enumerable.Range(0, iterationCount)) | |
{ | |
TestNoCast(); | |
TestCast(); | |
TestCast(); | |
TestNoCast(); | |
} | |
} | |
static double Average(double[] values) | |
{ | |
return 1.0 * values.Sum() / values.Length; | |
} | |
static double StandardDeviation(double average, double[] values) | |
{ | |
return Math.Sqrt(values.Select(x => (x - average) * (x - average)).Sum() / values.Length); | |
} | |
static double Measure(Stopwatch sw, Action a) | |
{ | |
sw.Reset(); | |
sw.Start(); | |
a(); | |
sw.Stop(); | |
return sw.Elapsed.TotalMilliseconds; | |
} | |
static void TestNoCast() | |
{ | |
foreach (E e in Enum.GetValues(typeof(E))) | |
{ | |
DummyFunction(e); | |
} | |
} | |
static void TestCast() | |
{ | |
foreach (var e in (E[])Enum.GetValues(typeof(E))) | |
{ | |
DummyFunction(e); | |
} | |
} | |
static int dummy = 0; | |
static void DummyFunction(E e) | |
{ | |
if (e.ToString().Contains('1')) | |
{ | |
++dummy; | |
} | |
} | |
} | |
} |
Thanks for looking into this. Your results are interesting and your analysis is very thorough. I've updated the gist, and the conclusion. IMHO this still qualifies as a micro-optimization that's not worth your time. Although I agree that it is good to know, that using the cast consistently produces faster code, and it might be important in some applications.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I was interested in your result because I thought my calculations were correct.
At first I thought that there is a problem with StopWatch accuracy, because the function execution time is very short. When I do tests I increase the measurement accuracy by increasing the number of iterations and after measuring I divide the result by the number of iterations.
But... I ran your code and...
I found a mistake.
Have you looked at the content of
noCast
andcast
arrays? I only have 0 or 1 values, and a few others.You should use sw.Elapsed.TotalMilliseconds of type double in your
Measure
function.Look at my vision of this issue.