Как отремонтировать подгнивший дом

Вскоре после того, как компилятор "задышал" и приобрел относительнуюстабильность, мы стали систематически проводить его профилирование. GNU'шнаяпрограмма gprof выдавала длинные таблицы временных затрат отдельных функций, поэтим таблицам мы рисовали огромные, на несколько листов, графы реальныхвзаимосвязей модулей, пытаясь найти резервы быстродействия. Первый же анализпоказал, что около 40% времени тратится на операции со строками и библиотечныефункции ввода-вывода. Сначала это показалось естественным?—?любая идентификацияименованного объекта в программе предполагает сравнение имен. Поиск имени втаблицах?—?одна из базовых операций в любом компиляторе, и даже используятехнику хеширования, избежать прямого литерального сравнения идентификаторовневозможно. Однако цифра показалась нам все же чрезмерно большой. Исправитьположение без разрушения компилятора было крайне сложно, так как всевозможныеоперации с именами буквально пронизывали все модули. Это не являлось проектнойошибкой?—?полностью локализовать работу с именами невозможно, так как самасемантика языка определяет необходимость оперировать с именами практически навсех стадиях компиляции.

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

Точно по такой же схеме обошелся с компилятором мой коллега. Он "вынул" из негостарую схему хранения имен и заменил ее на усложненную, но более эффективную.Ключевой момент новой схемы состоял в обеспечении присутствия каждого имени всемантических таблицах в единственном экземпляре. Тогда вместо сравнениялитеральных изображений имен достаточно было сравнивать указатели на этипредставления. Алгоритмы модулей, использующих операции с именами, никак неизменились, однако в некоторых местах пришлось заменить тип IDENT,представляющий "старый" идентификатор в таблицах, заменить на xIDENT?—?прямойуказатель на единственную копию данного имени. Эту операцию можно было бысделать одной командой контекстной замены, но никакой редактор не смог быразобраться, где именно следовало ее производить, а где?—?оставитьпо-старому… В очередной раз мы "руками" перещупали весь компилятор. Послечетырех дней непрерывного труда компилятор разогнался на 25% (нагляднаястоимость литеральных сравнений строк в большой программе)!

Фрагмент модуля с усовершенствованной версией обработки имен с тех пор украшаеткомментарий:

/* Krotoff is a _very_ clever guy! */

Товарища не похвалишь, так и он тебя не похвалит.









 


Главная | В избранное | Наш E-MAIL | Прислать материал | Нашёл ошибку | Верх