首页 > 解决方案 > System.Action 是内部数组吗?+= 和 -= 运算符的效率

问题描述

我需要不断地向委托添加和删除操作,我应该使用哈希集而不是操作吗?

我目前拥有的:

System.Action _callbacks =null;

//...somewhere in code, from many different places (2000 places or so, every frame):
_callbacks -= anyFunction;
_callbacks += someOtherFunc; 

我可能会使用什么(基本上是回调的哈希集):

Hashset<FastFunc> _callbacks = new Hashset<FastFunc>();


//...somewhere in code, from many different places
_callbacks.add( new FastFunc(someOtherFunc) );

// works A LOT faster with hashsets  that System.Action does.  //(March2019 profiler)
// It remembers its hashcode once, then can provide it super-quickly every time it's required.
public class FastFunc{
    public System.Action _func;
    private int _hashCode;

    public FastFunc(System.Action function){
        _func = function;
        remember_HashCode(function);
    }

    public override int GetHashCode(){
        return _hashCode;
    }

    // important to override Equals as well, so that objects created from the same method
    // will be identical.
    public override bool Equals(object other){    
        System.Action otherAction = ((FastFunc)other)._func;

        bool isEqual =  otherAction.Method.Equals( _func.Method )  &&  otherAction.Target.Equals( _func.Target );
        return isEqual;
    }

    //only called once, during constructor
    void remember_HashCode(System.Action myFunc){
        _hashCode = myFunc.GetHashCode();
    }
}

有了这个 -= 和 += 运营商就可以订阅System.Action,还是不?

它是否在底层使用了一个数组,如果我们从它的起始索引中删除一些函数,它就必须向后移动?如果是这样,我猜 hashset 会是一个更好的选择 + 没有重复。

标签: c#

解决方案


多播委托的调用列表数组。

https://referencesource.microsoft.com/#mscorlib/system/multicastdelegate.cs,284

(文档已过时(代表可能在 .Net 1.0 中使用了链接的 linsts,但不再使用了)https://docs.microsoft.com/en-us/dotnet/api/system.multicastdelegate?view=netframework-4.8 )

您可以使用您的方法更快地进行添加/删除操作。事实上,AFAIR,WPF 就是这样做的。

不过,您需要小心多线程。


推荐阅读