Изначально был повторен способ хранения форматов ячеек как у Мокселя: в каждой ячейке хранится структура, описывающая форматирование ячейки (шрифт, цвет, рамки и т.д.) После создания конвертеров для Excel, способ хранения форматов Excel показался более привлекательным. У Excel есть некоторый набор всех шрифтов используемых в листе. Эти шрифты адресуются индексом. Также есть аналогичный набор всех форматов ячеек. Каждая ячейка содержит индекс своего формата. Как правило количество используемых форматов и шрифтов очень невелико и уж точно их гораздо меньше, чем ячеек. Поэтому такой способ позволяет получить очень значительную экономию памяти. Ну а так как программа, использующая меньше памяти, имеет больше шансов попасть в кеш процессора, то такой способ поднимает еще и скорость работы. Во всяком случае, теоретически.
Итак, на текущий момент, бОльшая часть работы по переходу на Excel-подобный способ хранения форматов завершена. Изменена организация данных в листе, переписаны конвертеры из/в Моксель, переписана отрисовка (остались только конвертеры для Excel). Один в один способ, конечно, задействовать не получилось (да и не надо). Это вызвано некоторыми различиями в расчете Мокселем конечного формата ячейки на основе собственного формата ячейки, формата ее строки и столбца и формата ячейки по умолчанию для листа в целом.
Тестирование потребления памяти производилось на файле mxl объемом 80Мб (136 тыс. строк). До перехода Йоксель потреблял на таком файле примерно 210–220 Мб памяти. После перехода потребление памяти стало составлять немного меньше 180 Мб. Выигрыш не такой уж большой. Но это объясняется тем, что далеко не все возможности форматирования реализованы. Поэтому размер структуры для описания формата ячейки – невелик. Если бы были реализованы все возможности, то потребление неоптимизированного варианта было значительно больше, а потребление оптимизированного варианта изменилось бы очень не значительно.
Так же улучшено поведение системы по отношению к потреблению памяти. Раньше для хранения текста ячеек использовался класс CString, который не отдает в Windows выделенную память. Это означает, что если мы однажды открыли большой моксель и съели 220 Мб, то даже после его закрытия 1С будет по прежнему занимать 220 Мб. Причем это не утечка памяти, а именно «оптимизация» выделения памяти – использование уже выделенной памяти должно производиться значительно быстрее, чем повторное выделение памяти. Сейчас прозведен переход на использование класса std::string, у которого не наблюдается такого поведения – после закрытия тяжелого мокселя память практически полностью возвращается в Windows.
Изменились скоростные характеристики конвертера из MXL. Раньше минимальное время для парсинга файла составляло 5 с. Сейчас это время стало составлять 8 с. Впрочем, минимальное время считалось по нескольким запускам загрузки, а, значит, при этом конвертер задействовал уже выделенную память. Поэтому 5 с являются «жульническими» :) Как и следовало ожидать основное время в новой загрузке стали занимать операции поиска формата ячейки во множестве существующих форматов и операции выделения памяти.
Интересно сравнение с Мокселем. Сразу после запуска 1С время открытия файла весом 80 Мб составляет 4 с. Потребление памяти составляет 270 Мб. Т.к. Моксель активно использует CString, то после закрытия файла 1С занимает практически те же 270 Мб. При повторном открытии тестового файла наблюдается странный эффект: время загрузки существенно увеличивается – буквально в несколько раз (потребление памяти не меняется). Чем это вызывается – не понятно. Может быть, это проявляется эффект «фрагментации» хипа? В Йокселе время открытия тестового файла практически стабильно.
В общем, теперь наблюдается определенная свобода для модификаций Йокселя. Потребление памяти можно увеличить практически в два раза без опасений получить продукт «хуже конкурента». Скоростные характеристики в целом хуже. Однако, скорость сама по себе достаточно приемлема (особенно, если учесть огромный размер тестового файла по меркам Мокселя – уже на файле весом 6–7 Мб с объединениями ячеек в Мокселе становится очень некомфортно работать). Также по памяти получается несколько преимуществ.