Осторожно! Сложение Делегатов!

Осторожно! Сложение Делегатов!

Сообщение Neodrop 09 фев 2010, 02:19

Знаете ли вы, что объявленная "такой удобной" операция сложения делегатов, даёт 15-20 кратную потерю скорости вызова их методов?
Вот простой код проверки:

Код: Выделить всё
delegate void TEst0();

    TEst0 t0, t1, t2;

     void   Start ()
    {
        t0 = new TEst0(Reaction);
        t1 = new TEst0(Reaction);
        t2 = new TEst0(Reaction0);
        t1 += t2;

        float startTime = Time.realtimeSinceStartup;
        for (int i = 0; i < 1000000; i++) t0();
        Debug.Log("1 delegate : " + (Time.realtimeSinceStartup - startTime));

        startTime = Time.realtimeSinceStartup;
        for (int i = 0; i < 1000000; i++) t1();
        Debug.Log("2 delegate : " + (Time.realtimeSinceStartup - startTime));
   }

    void Reaction()
    {

    }

    void Reaction0()
    {

    }


Вот, что мы имеем на выходе :

Изображение

В обычном приложении, это не смертельно. Но, если код нагрузный, то лучше помнить об этой особенности.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Осторожно! Сложение Делегатов!

Сообщение Tolking 09 фев 2010, 11:36

Я случайно сложил делегатов и прифигел! Так как отладчика нет :) офигевал около часа, пока не разобрался что это фича. :D

Собственно, а сколько потребуется времени для вызова двух делегатов?

Добавь в тест:

float startTime = Time.realtimeSinceStartup;
for (int i = 0; i < 1000000; i++) { t0();t2();};
Debug.Log("2 single delegate : " + (Time.realtimeSinceStartup - startTime));

Может окажется, что использовать сложение выгоднее?
Хотя опыт показывает что все удобства делаются за счет скорости...
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Осторожно! Сложение Делегатов!

Сообщение gnoblin 09 фев 2010, 11:41

Интересно, спс. :ymhug:
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Осторожно! Сложение Делегатов!

Сообщение Neodrop 09 фев 2010, 17:16

При последовательном вызове, времени тратиться на два вызова, в два раза больше, чем на один. Что за идиотский вопрос? Конечно я это проверял, просто ни кой это тут?
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Осторожно! Сложение Делегатов!

Сообщение Tolking 09 фев 2010, 18:08

Это здесь для чистоты эксмеримента.

Два делегата подряд вызываются у меня в 7 раз медленее чем один, а не в 2 раза. "Сдвоенный" вызывается в 46 раз медленее чем одиночный.
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Осторожно! Сложение Делегатов!

Сообщение AndrewSt 09 фев 2010, 18:35

Скажу сразу тест координально не верен.
Во первых вызывается он в методе start когда куче всего еще работает.
Во вторых не правильно вызывать пустые методы в делегате, Оптимизатор их может просто выкинуть.
В третьих как уже говорил Tolking нужно добавить вызов двух делегатов последовательно.

Далее я провел свои тесты и вот что получилось
1 delegate : 0,007606268
2 delegate : 0,01513314
1+1 delegate : 0,0151217
1 metod : 0,01012015
1+1 metod : 0,01782131
Т.е. получается что прогрышь в использовании делеготов совсем не заметен, может от силы 1%.

Вот мой код теста.
Скрытый текст:
Код: Выделить всё
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TestDelegat : MonoBehaviour
{
   delegate void TEst0();

   TEst0 t0, t1, t2;

   void Start()
   {
      t0 = new TEst0(Reaction);
      t1 = new TEst0(Reaction);
      t2 = new TEst0(Reaction0);
      t1 += t2;

      float startTime = Time.realtimeSinceStartup;
      for (int i = 0; i < 10000; i++)
         t0();
      Debug.Log("1 delegate : " + (Time.realtimeSinceStartup - startTime));

      startTime = Time.realtimeSinceStartup;
      for (int i = 0; i < 10000; i++)
         t1();
      Debug.Log("2 delegate : " + (Time.realtimeSinceStartup - startTime));

      startTime = Time.realtimeSinceStartup;
      for (int i = 0; i < 10000; i++)
      {
         t0();
         t2();
      }
      Debug.Log("1+1 delegate : " + (Time.realtimeSinceStartup - startTime));


      startTime = Time.realtimeSinceStartup;
      for (int i = 0; i < 10000; i++)
      {
         Reaction();
      }
      Debug.Log("1 metod : " + (Time.realtimeSinceStartup - startTime));

      startTime = Time.realtimeSinceStartup;
      for (int i = 0; i < 10000; i++)
      {
         Reaction();
         Reaction0();
      }
      Debug.Log("1+1 metod : " + (Time.realtimeSinceStartup - startTime));

   }

   void FixedUpdate()
   {
      Start();
   }

   void Reaction()
   {
      int sum = 0;
      for (int i = 0; i < 1000; i++)
         sum += i;
   }

   void Reaction0()
   {
      int sum = 0;
      for (int i = 0; i < 1000; i++)
         sum += i;
   }
}

Даже скажу больше :).
Стабильно вызов методов работает чуток медленнее.
В чем прикол не понимаю. :-w
AndrewSt
UNIт
 
Сообщения: 72
Зарегистрирован: 10 дек 2009, 13:36
Откуда: СПБ
  • ICQ


Вернуться в Tips & Tricks

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1