Здравствуйте, Erop, Вы писали:
Z>>>>это хак в любом случае, в зависимости от того документированный он или нет можно только подставлять разные эпитеты... типа "грязный хак", например CS>>>Я знаю use cases где это решение приносит значительный профит.
E>>Поподробнее не расскажешь?
E>^^^^^^^^^^^^ SUBJ ^^^^^^^^^^^^
Да собственно ничего особо нового. Имплементация все того же DOM.
Скажем есть такая иерархия:
class node: object
{
element* parent; ...
virtual void each_visual( std::function<void(node*)> );
}
class element: node
{
collection<attribute> attributes;
collection<holder<node>> nodes;
virtual void each_visual( std::function<void(node*)> ); // need specializationvirtual void layout_width( ... ); // need specialization virtual void layout_height( ... ); // need specialization virtual void render( ... ); // need specialization
// еще примерно 30 методов которые могут быть специализированы
}
Есть парсер который строит дерево состоящее из element/node. Дерево абстрактное, содержит HTML, SVG и прочий XML в навал — то что называется HTML5 нынче. Парсер ничего не знает (физически не может знать) про то какие кокретно элементы создаются.
Через какое-то время подтягиваются стили в которых говорится что
input[type="text"] - текстовый редактор.
input[type="hidden"] - вообще не виден.
ul.mytable { display:table }
ul.mytable > li { display:table-row }
Т.е. *после* того как дерево построенно нам нужно элементы *специализировать*.
Скажем элемент который описан как display:table должен стать instance of этого:
Причем специализация сугубо динамическая. По ходу жизни элемент может стать
display:none и обратно например. Или в зависимости от размеров окна иметь flow:vertical или flow:horizontal.
Короче: нужно иметь возможность дешевой (быстрой и без memory overhead) специализации существующего DOM.
Желательно чтобы такая специализация не создавала лишние уровни косвенности в вызовах методов.
Мои эксперименты показывают profit, причем значительный если использовать технику смены vtbl для специализации.
Ну и код упрощается — становится более прозрачным. Немного позже смогу это выразить в цифрах если интересно.
Пока черновые прикидки в узких местах дают 12-16% выигрыш по скорости по сравнению с pimpl который используется в текущей версии.
Здравствуйте, c-smile, Вы писали: CS>Мои эксперименты показывают profit, причем значительный если использовать технику смены vtbl для специализации. CS>Ну и код упрощается — становится более прозрачным. Немного позже смогу это выразить в цифрах если интересно. CS>Пока черновые прикидки в узких местах дают 12-16% выигрыш по скорости по сравнению с pimpl который используется в текущей версии.
Если использовать не pimpl, а impl (хранить не указатель на стратегию, а саму стратегию), то потерь из-за косвенности не будет. Кроме того, это позволит перегружать не только по display, но и по другим ортогональным стратегиям. И никаких хаков.
Здравствуйте, gegMOPO4, Вы писали: MOP>Здравствуйте, c-smile, Вы писали: CS>>Мои эксперименты показывают profit, причем значительный если использовать технику смены vtbl для специализации. CS>>Ну и код упрощается — становится более прозрачным. Немного позже смогу это выразить в цифрах если интересно. CS>>Пока черновые прикидки в узких местах дают 12-16% выигрыш по скорости по сравнению с pimpl который используется в текущей версии. MOP>Если использовать не pimpl, а impl (хранить не указатель на стратегию, а саму стратегию), то потерь из-за косвенности не будет. Кроме того, это позволит перегружать не только по display, но и по другим ортогональным стратегиям. И никаких хаков.
Э-э-э, что-то сглупил я. Не выйдет. Разве что реализовывать vtbl вручную.
Во всяком случае 12% (в узких местах) не стоят того, чтобы делать код настолько потенциально непереносимым и нерасширяемым. Есть более легальные способы борьбы за производительность.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Во всяком случае 12% (в узких местах) не стоят того, чтобы делать код настолько потенциально непереносимым и нерасширяемым. Есть более легальные способы борьбы за производительность.
И переносим и расширяем. И 12% это много. И у всех разные критерии того что хорошо.
Скажем если ты работаешь в Гугле и предложишь способ поднять скорость поиска на 12% это примерно значит что Гугл сможет сэкономить на железе.
12% стоимости их железа это и есть профит.
Здравствуйте, c-smile, Вы писали:
MOP>>Во всяком случае 12% (в узких местах) не стоят того, чтобы делать код настолько потенциально непереносимым и нерасширяемым. Есть более легальные способы борьбы за производительность.
CS>И переносим и расширяем. И 12% это много. И у всех разные критерии того что хорошо.
Я, если честно, так и не понял чего и как делает версия кода без хака.
То есть я понял, что ты собираешь некое дерево объектов, которым потом, отдельным проходом, приписываешь типы.
Это я понял, но я не понял как был устроен код, по сравнению с которым ты получил 12% прироста...
И что он вообще делает?
Судя по тому, что ты там писал, это какое-тот отображение данных. Не совсем понятно, зачем там супербыстрое переключение вообще?
Ну и не понятно что такого делают переопределяемые функции, что двойная диспечерезация их заметно тормозит.
Может надо подумать тогда о том, что вообще аиртуальные функции не нужны? Ещё 12% выиграешь...
В общем ничего не понятно.
Я бы задачу решал так, что имел бы какие-то миксины, указатели на которые и распихивал бы по узлам дерева.
А в самом дереве, или в базе узла, сделал бы NVI интерфейс, который транслирует вызовы методов, в вызовы миксина...
Казалось бы, NVI интерфейсы все подставятся, лишняя косвенность только добавится, но если это дорого, то может правда архитектуру пересмотреть в сторону юолее крупных виртуальных функций, например?
CS>Скажем если ты работаешь в Гугле и предложишь способ поднять скорость поиска на 12% это примерно значит что Гугл сможет сэкономить на железе.
О! А ты работаешь в Гугле?
CS>12% стоимости их железа это и есть профит.
В том Гугле, про который я в курсе, была фишка запускать всё на самых трешовых и бесплатных компах. Зато сразу на очень многочисленных кластерах!...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, c-smile, Вы писали: CS>Здравствуйте, gegMOPO4, Вы писали: MOP>>Во всяком случае 12% (в узких местах) не стоят того, чтобы делать код настолько потенциально непереносимым и нерасширяемым. Есть более легальные способы борьбы за производительность. CS>И переносим и расширяем. И 12% это много. И у всех разные критерии того что хорошо.
Эти 12% ведь были получены на синтетике? В составе большой программы, с учётом ввода/вывода/обработки, прирост будет много скромнее, на уровне погрешности (меньше 5% — можно во внимание не принимать, от сборки к сборке больше прыгать будет).
Но если вам так уж хочется использовать здесь хак, то, пожалуйста, вынесите его в отдельный класс display_type, без данных, и реализуйте всё внутри него, как в чёрном ящике. Чтобы легче было это дело локализировать и заменить, когда посыпется.
CS>Скажем если ты работаешь в Гугле и предложишь способ поднять скорость поиска на 12% это примерно значит что Гугл сможет сэкономить на железе. CS>12% стоимости их железа это и есть профит.
Когда через три года Гугл захочет мигрировать на армы, или компилироваться clang-ом, или в новых процессорах x86 реализуют какую-то фишку, а gcc её применит для оптимизации, и переход затянется на год, пока будут искать баги, возникшие по вашей вине, это будет не профит.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, c-smile, Вы писали:
MOP>>>Во всяком случае 12% (в узких местах) не стоят того, чтобы делать код настолько потенциально непереносимым и нерасширяемым. Есть более легальные способы борьбы за производительность.
CS>>И переносим и расширяем. И 12% это много. И у всех разные критерии того что хорошо.
E>Я, если честно, так и не понял чего и как делает версия кода без хака.
E>То есть я понял, что ты собираешь некое дерево объектов, которым потом, отдельным проходом, приписываешь типы. E>Это я понял, но я не понял как был устроен код, по сравнению с которым ты получил 12% прироста... E>И что он вообще делает?
Есть такой вариант:
static handler* pA = new handler_A();
static handler* pB = new handler_B();
class element
{
handler* ph;
void layout_width(...) { ph->do_layout_width(this, ...); }
void layout_height(...) { ph->do_layout_height(this, ...); }
void specialize(type) {
switch(type) {
case tA : ph = pA; break;
case tB : ph = pB; break; }
}
};
Что мы получаем в этом случае:
1) нет поля handler* ph; меньше памяти нужно на instance
2) нет дополнительной косвенности вызова.
3) количество параметров вызова требуемое ph->do_layout_*** меньше на единицу...
Поле handler* ph; в первом примере дублирует функционально VTBL в виде самописного лисапета.
А собственно зачем его дублировать когда оно есть и так?
E>Судя по тому, что ты там писал, это какое-тот отображение данных. Не совсем понятно, зачем там супербыстрое переключение вообще? E>Ну и не понятно что такого делают переопределяемые функции, что двойная диспечерезация их заметно тормозит. E>Может надо подумать тогда о том, что вообще аиртуальные функции не нужны? Ещё 12% выиграешь...
Вот ты смотришь на эту web страницу. Представь себе как бы ты имплементировал это всё хозяйство в C++
E>В общем ничего не понятно. E>Я бы задачу решал так, что имел бы какие-то миксины, указатели на которые и распихивал бы по узлам дерева. E>А в самом дереве, или в базе узла, сделал бы NVI интерфейс, который транслирует вызовы методов, в вызовы миксина...
Предложи вариант таких mix-ins. Как-то сложно это представить.
E>Казалось бы, NVI интерфейсы все подставятся, лишняя косвенность только добавится, но если это дорого, то может правда архитектуру пересмотреть в сторону юолее крупных виртуальных функций, например?
Архитектура и набор вызовов не с потолка взяты — определяются самой задачей — rendering HTML и SVG.
CS>>Скажем если ты работаешь в Гугле и предложишь способ поднять скорость поиска на 12% это примерно значит что Гугл сможет сэкономить на железе. E>О! А ты работаешь в Гугле?
Я работаю на себя. С Гуглом данная проблема никак не связана.
CS>>12% стоимости их железа это и есть профит. E>В том Гугле, про который я в курсе, была фишка запускать всё на самых трешовых и бесплатных компах. Зато сразу на очень многочисленных кластерах!...
Соотнеси http://www.google.com/green/ и идею понизить на 12% выхлоп CO2 от поиска.
Но это все лирика — к делу не относится.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Здравствуйте, c-smile, Вы писали: CS>>Здравствуйте, gegMOPO4, Вы писали: MOP>>>Во всяком случае 12% (в узких местах) не стоят того, чтобы делать код настолько потенциально непереносимым и нерасширяемым. Есть более легальные способы борьбы за производительность. CS>>И переносим и расширяем. И 12% это много. И у всех разные критерии того что хорошо.
MOP>Эти 12% ведь были получены на синтетике? В составе большой программы, с учётом ввода/вывода/обработки, прирост будет много скромнее, на уровне погрешности (меньше 5% — можно во внимание не принимать, от сборки к сборке больше прыгать будет).
Что тебе сказать... 12% в моем случае это важно. И пять важно.
Тебе повезло что ты работаешь в бизнесе где 5% не важно и "от сборки к сборке больше прыгать" допускается.
MOP>Но если вам так уж хочется использовать здесь хак, то, пожалуйста, вынесите его в отдельный класс display_type, без данных, и реализуйте всё внутри него, как в чёрном ящике. Чтобы легче было это дело локализировать и заменить, когда посыпется.
CS>>Скажем если ты работаешь в Гугле и предложишь способ поднять скорость поиска на 12% это примерно значит что Гугл сможет сэкономить на железе. CS>>12% стоимости их железа это и есть профит.
MOP>Когда через три года Гугл захочет мигрировать на армы, или компилироваться clang-ом, или в новых процессорах x86 реализуют какую-то фишку, а gcc её применит для оптимизации, и переход затянется на год, пока будут искать баги, возникшие по вашей вине, это будет не профит.
За три года на 12% гугл сделает больше чем потребутся заплатить программеру на написание примерно этого:
(Код выше выдран из .h файла генерерумого VS при создании COM классов — там всегда генерируется как C++ так и pure С формы интерфейсов)
Кстати CONST_VTBL в COM rpc имплементации это пустая декларация ибо там возможны ситуации когда vtbl динамически преключается (и кстати вообще может генерироваться).
Но это уже так — слишком в дебри.
Еще раз: зная как технически устроенна виртуальность можно её использовать для вящей пользы.
Аккуратно, с должной оберткой и в одном месте/декларации, а не по всему коду.
Можно конечно руками залезть и тот lpVtbl поменять на то что нужно. Но имхо new(instA) B() как раз более переносимо.
Здравствуйте, Alexander G, Вы писали:
AG>Здравствуйте, A13x, Вы писали:
A>>Уже лень если честно писать proof-of-concept примеры, сериалы ждут.
AG>http://codepad.org/Zz3wfMF3
Надо так:
#include <iostream>
using namespace std;
struct B
{
virtual void f() { cout << "B" << endl; };
void mutate();
};
struct D : B
{
virtual void f() { cout << "D" << endl; };
};
void B::mutate()
{
new (this) D();
}
int main()
{
B* p = new B();
p->f();
p->mutate();
p->f();
return 0;
}
Здравствуйте, c-smile, Вы писали:
CS>Еще раз: зная как технически устроенна виртуальность можно её использовать для вящей пользы.
На конкретной версии конкретного компилятора, вызванного с конкретными опциями.
Ибо техническая реализация за пределами стандарта.
Это все и есть признаки "грязного хака".
Никто не запрещает грязному хаку работать в каких-то случаях (вариант UB), но от этого он грязным хаком быть не перестанет.
Когда компилятор делает виртуальный вызов, он генерит нечто вроде (на псевдо-асме):
; vptr указывает на таблицу класса А
mov ($vptr), %eax ;грузим указатель на vtbl А в регистр eax
callq 0x4(%eax) ;зовем функцию в таблице класса А
твой хак зависит от того, генерит ли компилятор "mov ($vptr), %eax" перед _каждым_ виртуальным вызовом:
; vptr указывает на таблицу класса А
mov ($vptr), %eax ;грузим указатель на vtbl А в регистр eax
callq 0x4(%eax) ;зовем одну функцию в таблице класса А
mov ($vptr), %eax ;грузим указатель на vtbl А в регистр eax
callq 0x8(%eax) ;зовем другую функцию в таблице класса A (mutate)
; теперь vptr указывает на таблицу класса В
mov ($vptr), %eax ;грузим указатель на vtbl B в регистр eax
callq 0x16(%eax) ;зовем третью функцию в таблице класса B
потому что никто не запрещает компилятору загрузить vptr только один раз (избавившись от ненужной прогулки в память за адресом vtbl) и сгенерить код наподобие:
; vptr указывает на таблицу класса А
mov ($vptr), %eax ;грузим указатель на vtbl A в регистр eax
callq 0x4(%eax) ;зовем одну функцию в таблице класса A
callq 0x8(%eax) ;зовем другую функцию в таблице класса A (mutate)
; теперь vptr указывает на таблицу класса В
callq 0x16(%eax) ;зовем третью функцию в таблице класса A
и не заметить подмены vptr, случившейся внутри вызова mutate, в результате третья функция пойдет по старой таблице.
Так что твоему хаку нужны какие-то гарантии со стороны компилятора, что именно так все и будет и этот mov вставляется перед каждым callq. У тебя такие гарантии есть?
ЗЫ Почему-то сайт не раскрашивает все комментарии в асмовском коде, только последний
ЗЗЫ Возможно, объявление volatile всех указателей на самомодифицирующиеся классы и даст какую-никакую гарантию от данной оптимизации. А может и не даcт, все это вилами на UB писано.
Здравствуйте, c-smile, Вы писали:
E>>То есть я понял, что ты собираешь некое дерево объектов, которым потом, отдельным проходом, приписываешь типы. E>>Это я понял, но я не понял как был устроен код, по сравнению с которым ты получил 12% прироста... E>>И что он вообще делает?
CS>Есть такой вариант:
CS>
CS>static handler* pA = new handler_A();
CS>static handler* pB = new handler_B();
CS>class element
CS>{
CS> handler* ph;
CS> void layout_width(...) { ph->do_layout_width(this, ...); }
CS> void layout_height(...) { ph->do_layout_height(this, ...); }
CS> void specialize(type) {
CS> switch(type) {
CS> case tA : ph = pA; break;
CS> case tB : ph = pB; break; }
CS> }
CS>};
CS>
Это примерно и полагал, но я бы немного не так сделал, конечно.
1) Я бы перечисление type не заводил бы, а просто имел бы статические handler_A, handler_B и т. д. Ссылки на на них и использовал бы, в качестве tA, tВ и т. д.
2) Я так понимаю, что у тебя класс element полиморфный? Я бы постарался сделать его обычным. Типа просто структурой.
Но я всё равно не понял главного.
1) Что такого быстрого делают do_layout_width, do_layout_height и т. д., что на лишнем косвенном вызове можно сэкономить 12%?
Может их результат просто кэшировать, например, и прямо вот при переключении типа всё и считать?
2) Судя по наличию this в вызове ph->do_layout_width(this, ...) в element есть какие-то поля. Как они переживают перевызовы конструкторов? Или конструкторы ничего в полях не инициализируют, а поля инициализируются потом? Тогда есть риск того, что какое-то поле в каком-то сценарии останется неинициализированным...
То есть это тоже очень непонятное место тут. Так как если в element нет полей, то не понятно зачем вся эта красота. А если поля есть, то не понятно как это всё работает...
CS>Функционально вышесказанное есть:
<...> CS>Что мы получаем в этом случае: CS>1) нет поля handler* ph; меньше памяти нужно на instance
Тоже как-то непонятно. Я так понимаю, что element -- это узел в каком-то дереве? Так? Тогда у него есть просто кучи данных про дерево. Кроме того, я так понял, что там ещё есть и какие-то поля данных. Таки получается, что затраты памяти мелкие довольно. Кроме того, если так уж всё жёстко, то можно element сделать просто без виртуализации.
Или это сложно сделать, потому что дерево завязано на какую-то библиотеку?
CS>2) нет дополнительной косвенности вызова.
Не понятно. По идее это дёшево очень должно быть.
CS>3) количество параметров вызова требуемое ph->do_layout_*** меньше на единицу...
А много там параметров?
Кстати, а узкое место по памяти или по производительности? Просто мне так кажется, что намного прямее оптиизировать тут контейнер, в котором дерево лежит. А не хачить...
Хотя я так пока и не понял, что там у вас на самом деле происходит...
Да и вообще вам виднее.
Но я могу поделиться там опытом печальным, что вот я некое ПО разрабатывал-разрабатывал и всё хорошо было. Ну в смысле не только я, а много народу. А потом понадобилось перенести на Мэк внезапно. А потом под линукс, а теперь жизнь вообще тяжёлая стала. Надо на телефоны всё переносить. А на телефонах такие средства разработки, что я вас умоляю...
И вот все места, где кто-то когда-то что-то на кривой козе объехал вылезли, как миленькие. Так что все такие хаки хорошо бы контролировать. Кроме того, неразумно, IMHO, выбирать такую архитектуру, которая безальтернативно навязывает хаки...
А вдруг на какой-то платформе не повезёт?
Прикинь, как будет смешно, если ты, скажем, 5-й яблофон не поддержишь, хотя 4-ре первых поддерживал
Правда, если ты гугол, то ты можешь просто разработать своё компиллер под все целевые платформы
CS>Вот ты смотришь на эту web страницу. Представь себе как бы ты имплементировал это всё хозяйство в C++
Если надо быстро, то так же, как и на С
CS>Соотнеси http://www.google.com/green/ и идею понизить на 12% выхлоп CO2 от поиска.
Я так думаю, что надо провести зелёную акцию "день без гугла"...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, c-smile, Вы писали: CS>Что тебе сказать... 12% в моем случае это важно. И пять важно. CS>Тебе повезло что ты работаешь в бизнесе где 5% не важно и "от сборки к сборке больше прыгать" допускается.
Где-то в другом месте программы добавился или убрался оператор, сдвинулись функции, загрузчик иначе рандомизировал память — и уже время поплыло на несколько процентов. На современных компьютерах добиться стабильного результата невозможно.
CS>(Код выше выдран из .h файла генерерумого VS при создании COM классов — там всегда генерируется как C++ так и pure С формы интерфейсов)
Этот код написан производителем компилятора, который может гарантировать его работоспособность (на своём компиляторе). Вот когда вы будете поддерживать свой компилятор, то сможете безопасно лазить к нему в потроха (а лучше всего завести специальные прагмы и интрисики для переключения типа).
CS>Еще раз: зная как технически устроенна виртуальность можно её использовать для вящей пользы. CS>Аккуратно, с должной оберткой и в одном месте/декларации, а не по всему коду. CS>Можно конечно руками залезть и тот lpVtbl поменять на то что нужно. Но имхо new(instA) B() как раз более переносимо.
Хак остаётся хаком, о чём все и говорят. Вы хотя бы вынесите это в отдельное место и реализуйте нормальное безопасное решение, переключаемое условной компиляцией, чтобы легко можно было отключить. Ну и переключать так класс с данными — особенно рискованно. Сделайте, и правда, element без виртуальных функций, переключайте только handler.
Здравствуйте, jazzer, Вы писали: J>Так что твоему хаку нужны какие-то гарантии со стороны компилятора, что именно так все и будет и этот mov вставляется перед каждым callq. У тебя такие гарантии есть?
Причём, что примечательно, такая оптимизация приводит к тому же эффекту, что достигается с помощью хака — уменьшение на 1 обращения к памяти. Но для всего кода, а не только хаченого. А теперь эту оптимизацию придётся отключить.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Хак остаётся хаком, о чём все и говорят. Вы хотя бы вынесите это в отдельное место и реализуйте нормальное безопасное решение, переключаемое условной компиляцией, чтобы легко можно было отключить. Ну и переключать так класс с данными — особенно рискованно. Сделайте, и правда, element без виртуальных функций, переключайте только handler.
Если бы коллега c-smile более понятно описал что делает его программа, то можно было бы дать более вменяемый совет.
Насколько я его понял, у него есть какой-то разборщик HTML'ек, которым он что-то разбирает, потом как-то результат разбора модифицирует, а потом это всё показывает. При этом способ показа можно переключать.
Я так понимаю, что затык идёт по скорости реендринга.
Ну, казалось бы, пишем вообще POD структуру результата разбора, потом её же модифицируем, а потом пишем к этой POD-структуре несколько визуализаторов...
Всё будет бытсро и без накладных расходов, как по памяти, так и по времени. Можно ещё, кстати, и указатели корткими сделать.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали: E>Если бы коллега c-smile более понятно описал что делает его программа, то можно было бы дать более вменяемый совет. E>Насколько я его понял, у него есть какой-то разборщик HTML'ек, которым он что-то разбирает, потом как-то результат разбора модифицирует, а потом это всё показывает. При этом способ показа можно переключать. E>Я так понимаю, что затык идёт по скорости реендринга.
Да там всё понятно. Модификация — это наложение CSS, который меняет поведение. В частности, от свойства display зависит несколько методов. Причём методы эти для большинства имплементаций тривиальные (вроде return 0). Отсюда и получаются заметные без микроскопа 12% на обработке. Не уверен, правда, заметны ли они с учётом ввода/вывода и парсинга.
E>Ну, казалось бы, пишем вообще POD структуру результата разбора, потом её же модифицируем, а потом пишем к этой POD-структуре несколько визуализаторов... E>Всё будет бытсро и без накладных расходов, как по памяти, так и по времени. Можно ещё, кстати, и указатели корткими сделать.
Ну да, можно сэмулировать виртуальные таблицы вручную. Не так «красиво» и писанины больше, зато никаких претензий со стороны стандарта и никаких подводных камней. И предложенную jazzer гипотетическую оптимизацию (которая поломала бы хаченную версию) можно не ждать от компилятора, а безопасно провести вручную, что дало бы ещё 12%. Ну, это если кровь из носу надо.
Здравствуйте, gegMOPO4, Вы писали:
MOP>Да там всё понятно. Модификация — это наложение CSS, который меняет поведение. В частности, от свойства display зависит несколько методов. Причём методы эти для большинства имплементаций тривиальные (вроде return 0). Отсюда и получаются заметные без микроскопа 12% на обработке. Не уверен, правда, заметны ли они с учётом ввода/вывода и парсинга.
Дык вещи вроде display можно задавть просто флажком в элементе...
Мне не понятно, он HTML-viewer что ли пишет? Зачем? Ясно, что что-то похожее. Но прикольно, что больше никто такой хак не рвётся использовать.
MOP>Ну да, можно сэмулировать виртуальные таблицы вручную. Не так «красиво» и писанины больше, зато никаких претензий со стороны стандарта и никаких подводных камней. И предложенную jazzer гипотетическую оптимизацию (которая поломала бы хаченную версию) можно не ждать от компилятора, а безопасно провести вручную, что дало бы ещё 12%. Ну, это если кровь из носу надо.
Да не надо никаких таблиц и вообще всех этих С++ штук.
Ну просто на С пишем, но с контролем типов и всё
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Дык вещи вроде display можно задавть просто флажком в элементе...
Я так и не понял что ты предлагаешь. Можешь в конце концов код показать?
Я так понимаю что у тебя опыта Web разработки нет вообще. Хотя бы для себя.
Поэтому тебе сложно понять про что это все. Вариантов специализаций в современном HTML/CSS
столько что флажков не хватит. Скажем вот display property в CSS: http://www.w3schools.com/css/pr_class_display.asp
(Это примерно половина возможных враиантов)
E>Мне не понятно, он HTML-viewer что ли пишет?
Здравствуйте, Erop, Вы писали: E>Здравствуйте, gegMOPO4, Вы писали: MOP>>Да там всё понятно. Модификация — это наложение CSS, который меняет поведение. В частности, от свойства display зависит несколько методов. Причём методы эти для большинства имплементаций тривиальные (вроде return 0). Отсюда и получаются заметные без микроскопа 12% на обработке. Не уверен, правда, заметны ли они с учётом ввода/вывода и парсинга. E>Дык вещи вроде display можно задавть просто флажком в элементе...
Можно, конечно, в display просто enum хранить. Но тогда придётся делать по нему switch в каждой интересующей функции. А это не только почти наверняка медленнее виртуальных методов, но и неправильно методологически.
MOP>>Ну да, можно сэмулировать виртуальные таблицы вручную. Не так «красиво» и писанины больше, зато никаких претензий со стороны стандарта и никаких подводных камней. И предложенную jazzer гипотетическую оптимизацию (которая поломала бы хаченную версию) можно не ждать от компилятора, а безопасно провести вручную, что дало бы ещё 12%. Ну, это если кровь из носу надо. E>Да не надо никаких таблиц и вообще всех этих С++ штук. E>Ну просто на С пишем, но с контролем типов и всё
Ну да, реализация таблицы виртуальных методов на чистом C. Вот как выше для COM, только без хака. Честное и эффективное решение.
Тогда понятно. На С написать слишком сложно.
Ну тогда да, всегда есть вариант "как COM из-под С"...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском