1. C++ / Говнокод #4724

    +155

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    void XmlElementHandler::startElement(
                        const XMLCh* const uri,
                        const XMLCh* const localname,
                        const XMLCh* const qname,
                        const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs
                        )
    {
      static XmlContext *context = XmlContext::getInstance();
      static XmlParser *parser = XmlParser::getInstance();

    оптимизируем обращения к синглтонам. потому что одной невидимой глобальной переменной явно не достаточно. вот такое щасце в 30+ методах на реализации интерфейса к Xerces-C.

    Запостил: Dummy00001, 23 Ноября 2010

    Комментарии (14) RSS

    • Имхо, преждевременная оптимизация. С другой стороны - почему бы нет ?
      Ответить
      • где преждевременная оптимизация?
        я че-то неодупляю.

        XmlContext и XmlParser singleton classы?
        Ответить
        • внутри getInstance() скорее всего условие наличия объекта уже и создание его, если ещё не создан. Т.е. во всех случаях вызова getInstance(); как минимум один условный оператор. Объявляя в методе startElement() статические переменные получается избегать этих if'ов при 2ом и последующих вызовах. Поправьте, если не прав.
          Ответить
          • тут парсится XML: там такие дикие кучи строковых операций и выделений памяти, что те синглтоновы if'ы просто капля в море.
            Ответить
          • Не понимаю в чём выигрыш...
            Да, переменные статические; да, живут после завершения функции-члена. Но они же прямо в самом начале без всяких условий слева от присваивания. С чего бы вдруг не выполнять ::getInstance()? Может быть объект по дороге убили, и указатель стал неверный... Как быть уверенным, что в какой-нибудь момент не потребуется действительно "пересоздать" объект?
            Ответить
            • static переменная инициализируется один раз при определении.
              Ответить
              • показать все, что скрытоАккуратно.
                Статические переменные, по стандарту, инициализируются нулём ещё до первого использования.
                Здесь будет "="-присваивание, которое будет отрабатывать постоянно.

                Единожды инициализированные и неизменные величины -- константы.
                Ответить
                • Аккуратно. Вот вам для проверки:
                  #include <iostream>
                  using namespace std;
                  
                  int nextValue()
                  {
                  	static int v = 0;
                  	cout << "nextValue() called\n";
                  	return v++;
                  }
                  
                  int testStatic()
                  {
                  	static int sValue = nextValue();
                  	return sValue;
                  }
                  
                  int main()
                  {
                  	cout << testStatic() << endl;
                  	cout << testStatic() << endl;
                  	cout << testStatic() << endl;
                  	return 0;
                  }

                  Статически переменные инициализируются нулем, если их не инициализировали явно.
                  Ответить
                  • Да, признаю, виновен.
                    Декларация, конечно же, отработает единожды.
                    В коде именно она.
                    Меня передёрнуло, прошу прощение.
                    Будет экономия от вызовов.
                    Прошу прощения.
                    Ответить
                • вы не правы. статические переменные инициализируются только раз: либо 0 либо тем чем код их инициализирует. инициализация происходит перед первым входом в контекст (не MT-safe).

                  это как бы основное свойство стачиский переменных что они сохраняют свое значение между вызовами функции. инициализировать их постоянно идет против смысла ихнего существования.
                  Ответить
                  • Вот стандарт:
                    Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place.

                    Более того:
                    Every object of static storage duration shall be zero-initialized at program startup
                    Ответить
                  • static не MT-safe на модификацию
                    Ответить
          • template<typename _type_>
            _type_ *GetInstance()
            {
               static _type_ instance(...);
            
               return &instance;
            }

            XmlContext *context и XmlParser *parser я бы сделал static членами данных класса XmlElementHandler и добавил бы const перед *
            Ответить
    • В общем срочно читать Александреску, главу про синглтоны
      Ответить

    Добавить комментарий