简体   繁体   English

在C#中打开Guid的最有效方法

[英]Most efficient way to switch on a Guid in C#

So in C# the switch statement only supports integral types (not Guids), so a simple O(1) comparison table doesn't look possible. 所以在C#中,switch语句只支持整数类型(不是Guids),所以一个简单的O(1)比较表看起来不可能。

What is the most computationally efficient way to match on a Guid 什么是计算效率最高的Guid匹配方式

At first I thought 起初我想

if(gMyGuid == new Guid("VALUE"))
else if (gMyGuid == new Guid("VALUE2")
else if (gMyGuid == new Guid("VALUE3")
...
else if (gMyGuid == new Guid("VALUEn")

However by doing this I'm creating a new instance of the Guid each time for a comparison. 但是,通过这样做,我每次都要创建一个新的Guid实例进行比较。 I could convert the Guid to a string then compare on the string but the string comparison is a pretty long string for comparison. 我可以将Guid转换为字符串然后比较字符串,但字符串比较是一个非常长的字符串用于比较。

Any advise is gratefully received. 感谢任何建议。

You can create a System.Collections.Generic.Dictionary <Guid, ...> where ... is something useful to you. 您可以创建一个System.Collections.Generic.Dictionary <Guid, ...> ,其中...对您有用。

Upon program startup, fill the dictionary with the guids and values that you need to recognize. 程序启动时,使用您需要识别的guid和值填充字典。

Then, use the TryGetValue method of the dictionary to retrieve a value by its guid. 然后,使用字典的TryGetValue方法通过其guid检索值。

I haven't stated anything literal for ... because I don't know what you want to do with the guids. 我没有说明任何字面意思...因为我不知道你想用guids做什么。 Maybe you want to run some function, then a method pointer ( Func<T> or something like that) might be appropriate, or otherwise an interface type that provides the method you want to invoke. 也许你想运行一些函数,然后方法指针( Func<T>或类似的东西)可能是合适的,或者是一个提供你想要调用的方法的接口类型。 This depends on the context/purpose of that guid comparing code. 这取决于比较代码的guid的上下文/目的。

Maybe these links will answer your question... 也许这些链接会回答你的问题......

How expensive is a GUID cast and comparison vs a string comparison 与字符串比较相比,GUID强制转换和比较的成本是多少

Performance - using Guid object or Guid string as Key 性能 - 使用Guid对象或Guid字符串作为Key

If nothing else it contains a starting point for a program that can do benchmarks tests of any approach you wish to try. 如果没有其他任何内容,它包含一个程序的起点,可以对您希望尝试的任何方法进行基准测试。

with c#7 you can now use switch with Pattern Matching for this purpose. 使用c#7,您现在可以使用带有模式匹配的开关来实现此目的。

switch (gMyGuid )
{
    case var g when (g == new Guid("VALUE")):
        break;
    case var g when (g == new Guid("VALUE2")):
        break;
    case var g when (g == new Guid("VALUEN")):
        break;
    default:
        break;
}

This also works if you have defined static readonly new Guid"..") variables. 如果您已定义静态只读新Guid“..”)变量,这也有效。

Create the compare values as static so you only created them once. 将比较值创建为静态,因此您只创建一次。

At the top of your class add: 在课程顶部添加:

private static Guid guidVal1 = new Guid("VALUE");

And then in your method: 然后在你的方法中:

if(gMyGuid == guidVal1)
else if .... 

If you're really concerned about performance, the constructors using numeric arguments are faster than the Guid(string) constructor. 如果您真的关心性能,那么使用数字参数的构造函数比Guid(string)构造函数更快。 No strings involved and no need to parse anything. 不涉及任何字符串,也无需解析任何内容。

This is the implementation of one of them: 这是其中一个的实现:

public Guid(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
{
    this._a = a;
    this._b = b;
    this._c = c;
    this._d = d;
    this._e = e;
    this._f = f;
    this._g = g;
    this._h = h;
    this._i = i;
    this._j = j;
    this._k = k;
}

Sure, it's not as pretty to look at, but i think it's the fastest constructor possible. 当然,它看起来不那么漂亮,但我认为它是最快的构造函数。 Also, you could of course store all your comparison Guids in a Dictionary and use the values in it to store a handler for each. 此外,您当然可以将所有比较Guid存储在Dictionary并使用其中的值来存储每个的处理程序。

I don't know where your GUIDs are coming from, but you could consider refactoring the code into the strategy pattern to make it more maintainable as mentioned by a commenter. 我不知道您的GUID来自哪里,但您可以考虑将代码重构为策略模式,以使其更易于维护,如评论者所述。

This article is a good summary: 这篇文章是一个很好的总结:

http://jeremyjarrell.org/archive/2007/10/28/64.aspx http://jeremyjarrell.org/archive/2007/10/28/64.aspx

I'd create a HashSet(T) of Guids, initialize it at startup. 我创建一个Guids的HashSet(T),在启动时初始化它。

Instead of the lengty 'if , if, if ' you get a 而不是lengty'if,if,if'你得到了

if (GuidHashSet.Contains(gMyGuid)) {}

and you could add new Guids to the HashSet if required. 如果需要,您可以向HashSet添加新的Guids。 HashSet Contains() is an O(1) operation. HashSet Contains()是一个O(1)操作。

Make them all Guids (just once) as Guid == Guid uses the internal data of the Guid to compare them (equals is overloaded in Guid.cs). 让它们成为所有Guids(只需一次)作为Guid == Guid使用Guid的内部数据来比较它们(等于在Guid.cs中重载)。 So comparing Guid == Guid is fastest. 所以比较Guid == Guid是最快的。 Which the HastSet will do. HastSet会做什么。

The Guid equality operator (==) is overloaded so to compare just the values: Guid等于运算符(==)被重载,因此仅比较值:

http://msdn.microsoft.com/en-us/library/system.guid.op_equality(v=VS.90).aspx http://msdn.microsoft.com/en-us/library/system.guid.op_equality(v=VS.90).aspx

if(gMyGuid == myGuid)
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM