Самый быстрый способ вызвать метод - PullRequest
0 голосов
/ 21 июля 2010

Чтение эта статья Я нашел несколько способов вызова метода.

Способ вызова:

public static void SendData(string value) { }

Звонки:

delegate void MyDelegate(string value);

//Slow method - NOT RECOMMENDED IN PRODUCTION!        
SendData("Update");

// Fast method - STRONGLY RECOMMENDED FOR PRODUCTION!
MyDelegate d = new MyDelegate(SendData);
d.BeginInvoke("Update", null, null);

Это правда? Это быстрее?

Action send = () => Send("Update");
send();

Или, может быть, это?

Мне нужно вызвать метод в триггер SQL CLR с максимальной производительностью, чтобы иметь смысл даже небольшое увеличение скорости.

Ответы [ 5 ]

20 голосов
/ 21 июля 2010

Что "быстрее"?

1) Попросите Боба косить газон. Подождите, пока он не закончил. Тогда иди в торговый центр.

2) Попросите Боба косить газон. Иди в торговый центр, пока он косит твой газон.

Вторая техника намного быстрее доставит вас в торговый центр. Цена, которую вы платите, заключается в том, что вы не знаете, будет ли газон скашиваться к тому времени, когда вы вернетесь домой, или нет. С первой техникой вы знаете , что, когда вы вернетесь домой из торгового центра, газон будет подстрижен, потому что вы подождали, пока он не ушел в первую очередь. Если ваша логика зависит от знания того, что к тому времени, когда вы вернетесь, газон будет подстригаться, тогда вторая техника будет неправильной .

Теперь важный бит: Очевидно, что ни одна из техник не подстригает ваш газон быстрее, чем другая. Когда вы спрашиваете "что быстрее?" Вы должны указать , какую операцию вы измеряете скорость.

13 голосов
/ 21 июля 2010

Использование делегата не быстрее, чем прямой вызов метода (во всей реальности создание делегата и последующий вызов его будет более дорогим).

Причина, по которой это будет казаться быстрее, заключается в том, что напрямуювызов метода блокирует исполняющий поток во время выполнения метода.В вашем примере делегата метод вызывается асинхронно (с использованием BeginInvoke), поэтому вызывающий поток продолжает выполняться во время выполнения метода.

Кроме того, всякий раз, когда у вас есть вызов BeginInvoke для делегата, вы также должны иметь соответствующийEndInvoke, которого вам не хватает в вашем примере:

Является ли EndInvoke () необязательным, своего рода необязательным или определенно необязательным?

и

IanG on Tap: EndInvoke не является обязательным

2 голосов
/ 21 июля 2010

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

Попробуйте: измените BeginInvoke на Invoke - вызывающий теперь блокирует, так же, как обычно вызывает SendData.

Предполагая, что комментарии к коду не ваши (т. Е. "РЕКОМЕНДУЕТСЯ ДЛЯ ПРОИЗВОДСТВА"), я бы быстро нашел ответственного разработчика и убедился, что он знает о Delegate.BeginInvoke и том факте, что они делают свое приложение многопоточным, не осознавая это ...

Чтобы ответить на вопрос, прямой вызов метода всегда является самым быстрым способом - делегаты или рефлексия несут накладные расходы.

1 голос
/ 21 июля 2010

Обратите внимание, что в статье, которую вы цитируете, автор говорит о вызовах WCF, в частности, о необходимости вставки и обновления базы данных.

В этом конкретном случае следует отметить следующие ключевые моменты:

  • Работа выполняется на другой машине.
  • Единственная информация, которую вы получаете, это "Успех!" (обычно) или (иногда) «провал» (о котором автор, похоже, не заботится)

Следовательно, в этом конкретном случае , фоновый вызов был лучше. Для общего использования лучше использовать прямые звонки.

1 голос
/ 21 июля 2010

Наилучшим шансом для повышения производительности будет оптимизация кода в методе, который будет находиться в хранимой процедуре SQL CLR, которую вызовет триггер. Не могли бы вы опубликовать дополнительную информацию об этом?

...