Проблемы со скоростью с делегатами и структурами - PullRequest
4 голосов
/ 10 ноября 2011

Я столкнулся с некоторыми проблемами со скоростью в отношении структур и делегатов - возьмите следующий код консольного приложения:

public delegate string StringGetter();
public class LocalString
{
    public LocalString(string value)
    {
        this.value = value;
    }

    public StringGetter Getter
    {
        get
        {
            return new StringGetter(this.GetValue);
        }
    }

    private string GetValue()
    {
        return value;
    }

    private string value;
}


class Program
{
    static void Main(string[] args)
    {
        var start = DateTime.Now;
        for (int i = 0; i < 2000000; i++)
        {
            var val = new LocalString( "hello World" );
            val.Getter();
        }
        Console.WriteLine((DateTime.Now - start).TotalMilliseconds);
        Console.ReadKey();
    }
}

При выполнении на моей машине это занимает ~ 1,8 с ... Если я изменяю структуру на класс, она запускается в ~ 0,1 с. Я взглянул на базовый код сборки и код ROTOR с открытым исходным кодом, чтобы понять, почему и есть некоторый специальный код для делегатов, имеющих цель struct, которая, как я предполагаю, предназначена для обработки упаковки и распаковки в функции MethodDesc * COMDelegate :: GetDelegateCtor (TypeHandle DelegateType, MethodDesc * pTargetMethod, DelegateCtorArgs * pCtorData).

Еще один момент - если вы создадите это в VS2008 с таргетингом на .net 3.5, приложение будет работать быстрее, чем если бы вы запустили его на VS2010 с таргетингом на .net 3.5. Я не понял, почему это так.

Любые комментарии / лучшее просвещение приветствуются ...

С уважением Lee

1 Ответ

3 голосов
/ 10 ноября 2011

Трудно ответить точно, код поддержки CLR для делегатов - крепкий орешек. Мое лучшее предположение - это издержки, необходимые для отмены / упаковки значения структуры. Вызов делегата осуществляется через заглушку, которая сначала помещает значение в ячейку, чтобы можно было вызывать метод экземпляра. После вызова любые побочные эффекты метода должны быть скопированы обратно в исходную структуру. Это дорого по сравнению с простым вызовом метода экземпляра ссылочного типа, они очень быстро. Я не видел никаких доказательств для подтверждения жизнеспособности значения структуры, немного странного, но вполне может быть где-то там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...