/// <summary> /// Tests whether we should prefer a switch statement over an if statement. /// </summary> static bool UseCSharpSwitch(SwitchAnalysis analysis, out KeyValuePair <LongSet, ILInstruction> defaultSection) { if (!analysis.InnerBlocks.Any()) { defaultSection = default(KeyValuePair <LongSet, ILInstruction>); return(false); } defaultSection = analysis.Sections.FirstOrDefault(s => s.Key.Count() > MaxValuesPerSection); if (defaultSection.Key.IsEmpty) { return(false); } ulong valuePerSectionLimit = MaxValuesPerSection; if (!analysis.ContainsILSwitch) { // If there's no IL switch involved, limit the number of keys per section // much more drastically to avoid generating switches where an if condition // would be shorter. valuePerSectionLimit = Math.Min( valuePerSectionLimit, (ulong)analysis.InnerBlocks.Count); } var defaultSectionKey = defaultSection.Key; if (analysis.Sections.Any(s => !s.Key.SetEquals(defaultSectionKey) && s.Key.Count() > valuePerSectionLimit)) { return(false); } return(analysis.InnerBlocks.Any()); }
/// <summary> /// Tests whether we should prefer a switch statement over an if statement. /// </summary> static bool UseCSharpSwitch(SwitchAnalysis analysis, out KeyValuePair <LongSet, ILInstruction> defaultSection) { if (!analysis.InnerBlocks.Any()) { defaultSection = default(KeyValuePair <LongSet, ILInstruction>); return(false); } defaultSection = analysis.Sections.FirstOrDefault(s => s.Key.Count() > MaxValuesPerSection); if (defaultSection.Value == null) { // no default section found? // This should never happen, as we'd need 2^64/MaxValuesPerSection sections to hit this case... return(false); } ulong valuePerSectionLimit = MaxValuesPerSection; if (!analysis.ContainsILSwitch) { // If there's no IL switch involved, limit the number of keys per section // much more drastically to avoid generating switches where an if condition // would be shorter. valuePerSectionLimit = Math.Min( valuePerSectionLimit, (ulong)analysis.InnerBlocks.Count); } var defaultSectionKey = defaultSection.Key; if (analysis.Sections.Any(s => !s.Key.SetEquals(defaultSectionKey) && s.Key.Count() > valuePerSectionLimit)) { // Only the default section is allowed to have tons of keys. // C# doesn't support "case 1 to 100000000", and we don't want to generate // gigabytes of case labels. return(false); } return(true); }