Ray*_*Ray 26 c# performance enums dictionary casting
我的应用程序有很多不同的查找值,这些值永远不会改变,例如美国.我想使用枚举,而不是将它们放入数据库表中.
但是,我确实意识到这样做需要一些枚举和大量的"int"和"string"来自我的枚举.
另外,我看到有人提到使用Dictionary <>作为查找表,但枚举实现似乎更清晰.
所以,我想问一下是否保留并传递很多枚举并将它们转换为性能问题,还是应该使用查找表方法,哪个表现更好?
编辑:需要转换为ID以存储在其他数据库表中.
Jon*_*eet 35
从int枚举到枚举非常便宜......它比字典查找更快.基本上它是一个无操作,只是将位复制到具有不同概念类型的位置.
将字符串解析为枚举值将稍微慢一些.
我怀疑这对你来说是一个瓶颈但是你这样做,说实话......不知道你在做什么,有点难以推荐超出正常的"写最简单,模式可读和可管理的可维护代码,然后检查它是否运行良好."
Str*_*ior 16
你不会注意到两者之间在性能上的巨大差异,但我仍然建议使用词典,因为它将在未来为你提供更多的灵活性.
首先,C#中的Enum不能像Java一样自动拥有与之关联的类,因此如果要将其他信息与状态(全名,Capital City,Postal缩写等)相关联,则创建一个UnitedState类将所有信息打包到一个集合中更容易.
而且,即使你认为这个值永远不会改变,它也不是完全不可改变的.例如,你可以想象有一个新的要求包括领土.或者,您可能需要允许加拿大用户查看加拿大省的名称.如果您将此集合视为任何其他数据集合(使用存储库从中检索值),您稍后可以选择更改存储库实现以从其他来源(数据库,Web服务,会话等)提取值. ).枚举不太通用.
关于性能参数:请记住,您不只是将Enum强制转换为int:您还在该枚举上运行ToString(),这会增加相当多的处理时间.考虑以下测试:
const int C = 10000;
int[] ids = new int[C];
string[] names = new string[C];
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i< C; i++)
{
    var id = (i % 50) + 1;
    names[i] = ((States)id).ToString();
}
sw.Stop();
Console.WriteLine("Enum: " + sw.Elapsed.TotalMilliseconds);
var namesById = Enum.GetValues(typeof(States)).Cast<States>()
                .ToDictionary(s => (int) s, s => s.ToString());
sw.Restart();
for (int i = 0; i< C; i++)
{
    var id = (i % 50) + 1;
    names[i] = namesById[id];
}
sw.Stop();
Console.WriteLine("Dictionary: " + sw.Elapsed.TotalMilliseconds);
结果:
Enum: 26.4875
Dictionary: 0.7684
因此,如果性能确实是您最关心的问题,那么词典绝对是您的选择.然而,我们在这里谈论如此快速的时间,在我甚至不关心速度问题之前,还有其他六个问题需要解决.
C#中的枚举不是为了提供值和字符串之间的映射而设计的.它们旨在提供强类型常量值,您可以在代码中传递它们.这样做的两个主要优点是:
与Java不同,C#不会自动检查强制转换值以确保它们是有效的(myState = (States)321),因此如果不手动执行,则不会对输入进行任何运行时数据检查.如果您没有明确引用状态的代码("States.Oklahoma"),那么您不会从上面的#2获得任何值.这使得#1成为使用枚举的唯一真正原因.如果这是一个足够好的理由,那么我建议使用枚举而不是整数作为键值.然后,当您需要字符串或与状态相关的其他值时,请执行字典查找.
这是我如何做到的:
public enum StateKey{
    AL = 1,AK,AS,AZ,AR,CA,CO,CT,DE,DC,FM,FL,GA,GU,
    HI,ID,IL,IN,IA,KS,KY,LA,ME,MH,MD,MA,MI,MN,MS,
    MO,MT,NE,NV,NH,NJ,NM,NY,NC,ND,MP,OH,OK,OR,PW,
    PA,PR,RI,SC,SD,TN,TX,UT,VT,VI,VA,WA,WV,WI,WY,
}
public class State
{
    public StateKey Key {get;set;}
    public int IntKey {get {return (int)Key;}}
    public string PostalAbbreviation {get;set;}
}
public interface IStateRepository
{
    State GetByKey(StateKey key);
}
public class StateRepository : IStateRepository
{
    private static Dictionary<StateKey, State> _statesByKey;
    static StateRepository()
    {
        _statesByKey = Enum.GetValues(typeof(StateKey))
        .Cast<StateKey>()
        .ToDictionary(k => k, k => new State {Key = k, PostalAbbreviation = k.ToString()});
    }
    public State GetByKey(StateKey key)
    {
        return _statesByKey[key];
    }
}
public class Foo
{
    IStateRepository _repository;
    // Dependency Injection makes this class unit-testable
    public Foo(IStateRepository repository) 
    {
        _repository = repository;
    }
    // If you haven't learned the wonders of DI, do this:
    public Foo()
    {
        _repository = new StateRepository();
    }
    public void DoSomethingWithAState(StateKey key)
    {
        Console.WriteLine(_repository.GetByKey(key).PostalAbbreviation);
    }
}
这条路:
Enum.ToString().[咕噜]
| 归档时间: | 
 | 
| 查看次数: | 16760 次 | 
| 最近记录: |