查找 GUID 的快速方法

发布于 2024-08-26 12:50:16 字数 321 浏览 3 评论 0原文

我有很多(+2000)个 GUID(在某些网络类中),我的程序在收到消息时必须找到其中一个并执行与之相关的工作。
积极的一点是我有一个硬代码生成器,但最快的方法是我的目标(而且我不知道如何实现它)。

我的代码应该做这样的事情:

switch(received guid)  
{  
case guid1: do job 1; break;  
case guid2: do job 2; break;  
case guid3: do job 3; break;  
case guid4: do job 4; break;  
....  
}  

I have lots(+2000) of GUIDs(in some network class) and my program must find one of them when it receives a message and do the job associated with it.
the positive point is i have a hard-code generator, but the fastest way is my goal(and i don't know how to implement it).

my code should do something like this:

switch(received guid)  
{  
case guid1: do job 1; break;  
case guid2: do job 2; break;  
case guid3: do job 3; break;  
case guid4: do job 4; break;  
....  
}  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

凡间太子 2024-09-02 12:50:16

您可以创建一个字典,其中 Guid 作为键,委托引用作为值。这将确保快速查找。

You could create a Dictionary with the Guid as the key and a delegate reference as the value. That would ensure fast lookups.

贵在坚持 2024-09-02 12:50:16

创建一个用于执行作业的接口,然后实现 2000 个执行该工作的类,每个类都知道自己的 guid。然后使用其 guid 作为键将类添加到字典中。然后,当您获得 guid 时,您可以在字典中查找该对象并调用接口上的方法。

public interface IJobDoer
{
    void DoJob();
    Guid Guid{get;}
}

public class FirstJobType : IJobDoer
{
    void DoJob()
    {
     /// whatever...
    }
    Guid Guid { get{return "insert-guid-here";}}
}

Create an interface for doing the Job, then implement 2000 classes which do the work, each of which knows its own guid. Then add the classes to a dictionary using its guid as the key. Then when you get the guid, you look the object up in the dictionary and call the method on the interface.

public interface IJobDoer
{
    void DoJob();
    Guid Guid{get;}
}

public class FirstJobType : IJobDoer
{
    void DoJob()
    {
     /// whatever...
    }
    Guid Guid { get{return "insert-guid-here";}}
}
来日方长 2024-09-02 12:50:16

使用将 Guid 映射到代表任务的委托或类的哈希表,例如 DictionaryDictionary

Use a hashtable which maps Guid to a delegate or a class that represents the task, such as Dictionary<Guid, Action> or Dictionary<Guid, Task>.

白衬杉格子梦 2024-09-02 12:50:16

Dictionary 可能比 switch 语句更快。

但你必须进行分析才能确定。

A Dictionary<Guid, JobDelegate> would probably be faster than a switch statement.

But you would have to profile to be sure.

孤者何惧 2024-09-02 12:50:16

我喜欢展示其他人已经提出的字典方法的变体。在此解决方案的基础上,您可以执行以下操作。

1 定义一个基类:

public abstract class JobDoer
{
    public abstract void DoJob();
}

2 定义一个用于装饰工作执行者的属性。

public sealed class JobDoerAttribute : Attribute
{
    JobDoerAttribute(string jobDoerId)
    {
        this.JobDoerId = new Guid(jobDoerId);
    }

    public Guid JobDoerId { get; private set; }
}

3 定义用该属性修饰的实际作业执行者类。例如:

[JobDoer("063EE2B2-3759-11DF-B738-49BB56D89593")]
public sealed class SpecificJobDoer : JobDoer
{
    public override void DoJob()
    {
        // Do a specific job
    }
}

4 定义一个 JobDoerFactory,允许通过属性中定义的 Id 检索 JobDoer 实例:

public static class JobDoerFactory
{
    static Dictionary<Guid, JobDoer> cache;

    static JobDoerFactory()
    {
        // Building the cache is slow, but it will only run once 
        // during the lifetime of the AppDomain.
        cache = BuildCache();
    }

    public static JobDoer GetInstanceById(Guid jobDoerId)
    {
        // Retrieving a JobDoer is as fast as using a switch statement.
        return cache[jobDoerId];
    }

    private static Dictionary<Guid, JobDoer> BuildCache()
    {
        // See implementation below.
    }
}

BuildCache 方法中,您可以可以使用反射来加载 JobDoer 实例。

private static Dictionary<Guid, JobDoer> BuildCache()
{
    // This is a bit naive implementation; we miss some error checking,
    // but you'll get the idea :-)
    var jobDoers =
       (from assembly in AppDomain.CurrentDomain.GetAssemblies()
        from type in assembly.GetTypes()
        where type.IsSubclassOf(typeof(JobDoer))
        let attributes =
            type.GetCustomAttribute(typeof(JobDoerAttribute), true)
        where attributes.Length > 0
        let attribute = attributes[0] as JobDoerAttribute
        select new { attribute.JobDoerId, type }).ToArray();

    var cache = new Dictionary<Guid, JobDoer>(jobDoers.Length);

    foreach (jobDoer in jobDoers)
    {
        // Note that actually a single instance of the job doer is
        // cached by ID. This means that every Job Doer must be 
        // thread-safe and usable multiple times. If this is not 
        // feasable, you can also create store a set of Func<JobDoer> 
        // objects that enable creating a new instance on each call.
        cache[jobDoer.JobDoerId] =
            (JobDoer)Activator.CreateInstance(jobDoer.type);
    }
    return cache;
}

我没有测试这段代码,所以我不知道它是否可以编译,但几年前我在一个项目中使用了这种机制。这样就可以很容易地定义新类,而不需要将其连接到某些字典。它是在运行时自动完成的。

这可能看起来有点大材小用,但如果您有超过 2000 个 JobDoer 类,这会对您有很大帮助。

更新:
请注意,如果您不喜欢 JobDoerAttribute 的想法,您还可以将其实现为抽象 JobDoer 类上的抽象属性。但是,我发现使用属性使代码非常明确且富有表现力。

I like to show a variation of the dictionary approach others already proposed. Building on this that solution, you could do the following.

1 Define a base class:

public abstract class JobDoer
{
    public abstract void DoJob();
}

2 Define a attribute for decoration of job doers.

public sealed class JobDoerAttribute : Attribute
{
    JobDoerAttribute(string jobDoerId)
    {
        this.JobDoerId = new Guid(jobDoerId);
    }

    public Guid JobDoerId { get; private set; }
}

3 Define the actual job doer classes that are decorated with that attribute. For instance:

[JobDoer("063EE2B2-3759-11DF-B738-49BB56D89593")]
public sealed class SpecificJobDoer : JobDoer
{
    public override void DoJob()
    {
        // Do a specific job
    }
}

4 Define a JobDoerFactory that enables retrieving JobDoer instances by their Id as it is defined in the attribute:

public static class JobDoerFactory
{
    static Dictionary<Guid, JobDoer> cache;

    static JobDoerFactory()
    {
        // Building the cache is slow, but it will only run once 
        // during the lifetime of the AppDomain.
        cache = BuildCache();
    }

    public static JobDoer GetInstanceById(Guid jobDoerId)
    {
        // Retrieving a JobDoer is as fast as using a switch statement.
        return cache[jobDoerId];
    }

    private static Dictionary<Guid, JobDoer> BuildCache()
    {
        // See implementation below.
    }
}

In the BuildCache method, you can do the loading of JobDoer instances by using reflection.

private static Dictionary<Guid, JobDoer> BuildCache()
{
    // This is a bit naive implementation; we miss some error checking,
    // but you'll get the idea :-)
    var jobDoers =
       (from assembly in AppDomain.CurrentDomain.GetAssemblies()
        from type in assembly.GetTypes()
        where type.IsSubclassOf(typeof(JobDoer))
        let attributes =
            type.GetCustomAttribute(typeof(JobDoerAttribute), true)
        where attributes.Length > 0
        let attribute = attributes[0] as JobDoerAttribute
        select new { attribute.JobDoerId, type }).ToArray();

    var cache = new Dictionary<Guid, JobDoer>(jobDoers.Length);

    foreach (jobDoer in jobDoers)
    {
        // Note that actually a single instance of the job doer is
        // cached by ID. This means that every Job Doer must be 
        // thread-safe and usable multiple times. If this is not 
        // feasable, you can also create store a set of Func<JobDoer> 
        // objects that enable creating a new instance on each call.
        cache[jobDoer.JobDoerId] =
            (JobDoer)Activator.CreateInstance(jobDoer.type);
    }
    return cache;
}

I didn't test this code, so I don't know if it compiles, but I used this mechanism in a project a few years back. This way it is easy to define new classes, without the need to hook it up to some dictionary. It is done automatically at runtime.

This might look a bit like overkill, but if you have +2000 JobDoer classes, this could help you a lot.

Update:
Note that if you don't like the idea of the JobDoerAttribute, you can also implement it as abstract property on the abstract JobDoer class. However, I've found using an attribute makes the code very explicit and expressive.

画骨成沙 2024-09-02 12:50:16

使用 Guid 和 Action 创建一个字典,然后对其进行搜索。

Create a Dictionary with Guid And Action, and search over it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文