diff --git "a/src/BenchmarkOneScript/core/custom-jason/\320\232\320\273\320\260\321\201\321\201\321\213/\320\224\320\265\321\201\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200JsonBench.os" "b/src/BenchmarkOneScript/core/custom-jason/\320\232\320\273\320\260\321\201\321\201\321\213/\320\224\320\265\321\201\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200JsonBench.os" index ba99a15..394afef 100644 --- "a/src/BenchmarkOneScript/core/custom-jason/\320\232\320\273\320\260\321\201\321\201\321\213/\320\224\320\265\321\201\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200JsonBench.os" +++ "b/src/BenchmarkOneScript/core/custom-jason/\320\232\320\273\320\260\321\201\321\201\321\213/\320\224\320\265\321\201\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200JsonBench.os" @@ -26,6 +26,14 @@ // Перем Конвертеры; +// Кэш обработчиков для каждого типа +// +Перем КэшОбработчиков; + +// Кэш свойств типов +// +Перем КэшСвойствТипов; + #КонецОбласти #Область ОбработчикиСобытий @@ -55,6 +63,9 @@ Конвертеры = пКонвертеры; КонецЕсли; + КэшОбработчиков = Новый Соответствие(); + КэшСвойствТипов = Новый Соответствие(); + КонецПроцедуры #КонецОбласти @@ -210,33 +221,32 @@ Функция ПреобразоватьПользовательскийТип(Объект, ТипОбъекта) Результат = Новый(ТипОбъекта); - СвойстваОбъекта = Рефлектор.ПолучитьТаблицуСвойств(ТипОбъекта, Истина); - СвойстваПоИменамПолей = Новый Соответствие(); - - Для Каждого Свойство Из СвойстваОбъекта Цикл - АннотацияСериализуемое = РаботаСАннотациями.ПолучитьАннотацию(Свойство, "Сериализуемое"); - ИмяСвойства = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(АннотацияСериализуемое, "Значение", Свойство.Имя); - - СвойстваПоИменамПолей.Вставить(ИмяСвойства, Свойство); - КонецЦикла; Если ЭтоСтруктураИлиСоответствие(Объект) Тогда - + + СвойстваТипа = КэшСвойствТипов[ТипОбъекта]; + Если СвойстваТипа = Неопределено Тогда + СвойстваТипа = ПрочитатьСвойстваТипа(ТипОбъекта); + КонецЕсли; + Для Каждого КлючИЗначение Из Объект Цикл - Свойство = СвойстваПоИменамПолей[КлючИЗначение.Ключ]; - Если Свойство = Неопределено Тогда + ОписаниеСвойства = СвойстваТипа[КлючИЗначение.Ключ]; + Если ОписаниеСвойства = Неопределено Тогда Продолжить; КонецЕсли; - ИмяСвойства = Свойство.Имя; ЗначениеСвойства = КлючИЗначение.Значение; - ТипыСвойства = ПолучитьТипыСвойства(Свойство, ЗначениеСвойства); - ТипСвойства = ТипыСвойства.БазовыйТип; - ТипЭлементов = ТипыСвойства.ТипЭлементов; + ИмяСвойства = ОписаниеСвойства.ИмяСвойства; + ТипСвойства = ОписаниеСвойства.БазовыйТип; + ТипЭлементов = ОписаниеСвойства.ТипЭлементов; + ДесериализуемыеКлючи = ОписаниеСвойства.ДесериализуемыеКлючи; + + Если Не ЗначениеЗаполнено(ТипСвойства) Тогда + ТипСвойства = ТипЗнч(ЗначениеСвойства); + КонецЕсли; - ДесериализуемыеКлючи = ПолучитьДесериализуемыеКлючи(Свойство); ЗначениеСвойства = ПреобразоватьОбъектДесериализации(ЗначениеСвойства, ТипСвойства, ТипЭлементов, @@ -263,11 +273,46 @@ КонецФункции -Функция ПолучитьТипыСвойства(Свойство, ЗначениеСвойства) +Функция ПрочитатьСвойстваТипа(Тип) + + ОписаниеСвойств = Новый Соответствие(); + + СвойстваОбъекта = Рефлектор.ПолучитьТаблицуСвойств(Тип, Истина); + + Для Каждого Свойство Из СвойстваОбъекта Цикл + + АннотацияСериализуемое = РаботаСАннотациями.ПолучитьАннотацию(Свойство, "Сериализуемое"); + Имя = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(АннотацияСериализуемое, "Значение", Свойство.Имя); + + Если Не ЗначениеЗаполнено(Имя) Тогда + Имя = Свойство.Имя; + КонецЕсли; + + ТипыСвойства = ПолучитьТипыСвойства(Свойство); + + ДесериализуемыеКлючи = ПолучитьДесериализуемыеКлючи(Свойство); + + ОписаниеСвойства = Новый Структура(); + ОписаниеСвойства.Вставить("ИмяСвойства", Свойство.Имя); + ОписаниеСвойства.Вставить("БазовыйТип", ТипыСвойства.БазовыйТип); + ОписаниеСвойства.Вставить("ТипЭлементов", ТипыСвойства.ТипЭлементов); + ОписаниеСвойства.Вставить("ДесериализуемыеКлючи", ДесериализуемыеКлючи); + + ОписаниеСвойств.Вставить(Имя, ОписаниеСвойства); + + КонецЦикла; + + КэшСвойствТипов.Вставить(Тип, ОписаниеСвойств); - ОписаниеСвойства = Новый Структура(); - ОписаниеСвойства.Вставить("БазовыйТип", ТипЗнч(ЗначениеСвойства)); - ОписаниеСвойства.Вставить("ТипЭлементов"); + Возврат ОписаниеСвойств; + +КонецФункции + +Функция ПолучитьТипыСвойства(Свойство) + + ТипыСвойства = Новый Структура(); + ТипыСвойства.Вставить("БазовыйТип"); + ТипыСвойства.Вставить("ТипЭлементов"); КонтейнерАннотаций = Новый КонтейнерАннотаций; КонтейнерАннотаций.ДобавитьАннотацию(Тип("АннотацияТип")); @@ -294,16 +339,16 @@ ТипСвойства = ОбъектАннотации.ТипЗначения(); Если ТекущийРежимДляКаждого = Неопределено Тогда - ОписаниеСвойства.БазовыйТип = ТипСвойства; + ТипыСвойства.БазовыйТип = ТипСвойства; ИначеЕсли ТекущийРежимДляКаждого = "Значение" Тогда - ОписаниеСвойства.ТипЭлементов = ТипСвойства; + ТипыСвойства.ТипЭлементов = ТипСвойства; КонецЕсли; КонецЕсли; КонецЦикла; - Возврат ОписаниеСвойства; + Возврат ТипыСвойства; КонецФункции @@ -325,14 +370,18 @@ Процедура ВызватьМетодПослеДесериализации(ПользовательскийОбъект, ПрочитанныеСвойства) - ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(ТипЗнч(ПользовательскийОбъект)); + Тип = ТипЗнч(ПользовательскийОбъект); - Для Каждого СвойстваМетода Из ТаблицаМетодов Цикл + Обработчики = КэшОбработчиков[Тип]; + Если Обработчики = Неопределено Тогда + Обработчики = ПрочитатьОбработчикиТипа(Тип); + КонецЕсли; - АннотацияПослеДесериализации = РаботаСАннотациями.НайтиАннотацию(СвойстваМетода.Аннотации, "ПослеДесериализации"); - Если АннотацияПослеДесериализации = Неопределено Тогда - Продолжить; - КонецЕсли; + Если Обработчики["ПослеДесериализации"] = Неопределено Тогда + Возврат; + КонецЕсли; + + Для Каждого СвойстваМетода Из Обработчики["ПослеДесериализации"] Цикл ПараметрыМетода = Новый Массив(); @@ -349,6 +398,42 @@ КонецПроцедуры +Функция ПрочитатьОбработчикиТипа(Тип) + + ИменаОбработчиков = Новый Массив(); + ИменаОбработчиков.Добавить("ПослеДесериализации"); + + Обработчики = Новый Соответствие(); + + ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(Тип); + + Для Каждого СвойстваМетода Из ТаблицаМетодов Цикл + + Для Каждого ИмяОбработчика Из ИменаОбработчиков Цикл + + СвойстваМетодов = Обработчики[ИмяОбработчика]; + + Если СвойстваМетодов = Неопределено Тогда + СвойстваМетодов = Новый Массив(); + Обработчики[ИмяОбработчика] = СвойстваМетодов; + КонецЕсли; + + АннотацияОбработчика = РаботаСАннотациями.НайтиАннотацию(СвойстваМетода.Аннотации, ИмяОбработчика); + Если АннотацияОбработчика <> Неопределено Тогда + СвойстваМетодов.Добавить(СвойстваМетода); + Прервать; + КонецЕсли; + + КонецЦикла; + + КонецЦикла; + + КэшОбработчиков.Вставить(Тип, Обработчики); + + Возврат Обработчики; + +КонецФункции + Функция ЭтоСтруктураИлиСоответствие(Значение) Возврат ТипЗнч(Значение) = Тип("Структура") Или ТипЗнч(Значение) = Тип("Соответствие"); КонецФункции diff --git "a/src/BenchmarkOneScript/core/custom-jason/\320\232\320\273\320\260\321\201\321\201\321\213/\320\241\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200JsonBench.os" "b/src/BenchmarkOneScript/core/custom-jason/\320\232\320\273\320\260\321\201\321\201\321\213/\320\241\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200JsonBench.os" index ca01089..0ab825f 100644 --- "a/src/BenchmarkOneScript/core/custom-jason/\320\232\320\273\320\260\321\201\321\201\321\213/\320\241\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200JsonBench.os" +++ "b/src/BenchmarkOneScript/core/custom-jason/\320\232\320\273\320\260\321\201\321\201\321\213/\320\241\320\265\321\200\320\270\320\260\320\273\320\270\320\267\320\260\321\202\320\276\321\200JsonBench.os" @@ -27,6 +27,18 @@ // Перем Конвертеры; +// Кэш обработчиков для каждого типа +// +Перем КэшОбработчиков; + +// Кэш свойств для каждого типа +// +Перем КэшГеттеровСвойств; + +// Кэш свойств типов +// +Перем КэшСвойствТипов; + #КонецОбласти #Область ОбработчикиСобытий @@ -56,6 +68,10 @@ Конвертеры = пКонвертеры; КонецЕсли; + КэшОбработчиков = Новый Соответствие(); + КэшГеттеровСвойств = Новый Соответствие(); + КэшСвойствТипов = Новый Соответствие(); + КонецПроцедуры #КонецОбласти @@ -208,14 +224,18 @@ Процедура ВызватьМетодПередСериализацией(Объект, Результат, СтандартнаяОбработка) - ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(ТипЗнч(Объект)); + Тип = ТипЗнч(Объект); + + Обработчики = КэшОбработчиков[Тип]; + Если Обработчики = Неопределено Тогда + Обработчики = ПрочитатьОбработчикиТипа(Тип); + КонецЕсли; - Для Каждого СвойстваМетода Из ТаблицаМетодов Цикл + Если Обработчики["ПередСериализацией"] = Неопределено Тогда + Возврат; + КонецЕсли; - АннотацияПередСериализацией = РаботаСАннотациями.НайтиАннотацию(СвойстваМетода.Аннотации, "ПередСериализацией"); - Если АннотацияПередСериализацией = Неопределено Тогда - Продолжить; - КонецЕсли; + Для Каждого СвойстваМетода Из Обработчики["ПередСериализацией"] Цикл ПараметрыМетода = Новый Массив(); @@ -244,11 +264,72 @@ КонецПроцедуры +Функция ПрочитатьОбработчикиТипа(Тип) + + ИменаОбработчиков = Новый Массив(); + ИменаОбработчиков.Добавить("ПередСериализацией"); + + Обработчики = Новый Соответствие(); + + ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(Тип); + + Для Каждого СвойстваМетода Из ТаблицаМетодов Цикл + + Для Каждого ИмяОбработчика Из ИменаОбработчиков Цикл + + СвойстваМетодов = Обработчики[ИмяОбработчика]; + + Если СвойстваМетодов = Неопределено Тогда + СвойстваМетодов = Новый Массив(); + Обработчики[ИмяОбработчика] = СвойстваМетодов; + КонецЕсли; + + АннотацияОбработчика = РаботаСАннотациями.НайтиАннотацию(СвойстваМетода.Аннотации, ИмяОбработчика); + Если АннотацияОбработчика <> Неопределено Тогда + СвойстваМетодов.Добавить(СвойстваМетода); + Прервать; + КонецЕсли; + + КонецЦикла; + + КонецЦикла; + + КэшОбработчиков.Вставить(Тип, Обработчики); + + Возврат Обработчики; + +КонецФункции + Процедура ПрочитатьСериализуемыеПоля(Объект, Результат) - СвойстваОбъекта = Рефлектор.ПолучитьТаблицуСвойств(ТипЗнч(Объект), Истина); + Тип = ТипЗнч(Объект); + + СвойстваТипа = КэшСвойствТипов[Тип]; + Если СвойстваТипа = Неопределено Тогда + СвойстваТипа = ПрочитатьСвойстваТипа(Тип); + КонецЕсли; + + Для Каждого ОписаниеСвойства Из СвойстваТипа Цикл + + ЗначениеСвойства = Рефлектор.ПолучитьСвойство(Объект, ОписаниеСвойства.ИмяСвойства); + ЗначениеСвойства = ПреобразоватьОбъектСериализации(ЗначениеСвойства, ОписаниеСвойства.СериализуемыеКлючи); + + Если ОписаниеСвойства.Обязательное Или ЗначениеСвойства <> Неопределено Тогда + Результат.Вставить(ОписаниеСвойства.Имя, ЗначениеСвойства); + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Функция ПрочитатьСвойстваТипа(Тип) + + ОписаниеСвойств = Новый Массив(); + + СвойстваОбъекта = Рефлектор.ПолучитьТаблицуСвойств(Тип, Истина); Для Каждого СвойствоОбъекта Из СвойстваОбъекта Цикл + // Проверяем, не помечено ли поле как несериализуемое Несериализуемое = РаботаСАннотациями.НайтиАннотацию(СвойствоОбъекта.Аннотации, "Несериализуемое"); Если Несериализуемое <> Неопределено Тогда @@ -256,10 +337,10 @@ КонецЕсли; Обязательное = Ложь; - ИмяСвойства = СвойствоОбъекта.Имя; + Имя = СвойствоОбъекта.Имя; АннотацияСериализуемое = РаботаСАннотациями.НайтиАннотацию(СвойствоОбъекта.Аннотации, "Сериализуемое"); Если АннотацияСериализуемое <> Неопределено Тогда - ИмяСвойства = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(АннотацияСериализуемое, + Имя = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(АннотацияСериализуемое, "Значение", СвойствоОбъекта.Имя); @@ -270,19 +351,48 @@ СериализуемыеКлючи = ПолучитьСериализуемыеКлючи(СвойствоОбъекта); - ЗначениеСвойства = Рефлектор.ПолучитьСвойство(Объект, СвойствоОбъекта.Имя); - ЗначениеСвойства = ПреобразоватьОбъектСериализации(ЗначениеСвойства, СериализуемыеКлючи); - Если Обязательное ИЛИ ЗначениеСвойства <> Неопределено Тогда - Результат.Вставить(ИмяСвойства, ЗначениеСвойства); + ОписаниеСвойства = Новый Структура(); + ОписаниеСвойства.Вставить("Имя", Имя); + ОписаниеСвойства.Вставить("ИмяСвойства", СвойствоОбъекта.Имя); + ОписаниеСвойства.Вставить("Обязательное", Обязательное); + ОписаниеСвойства.Вставить("СериализуемыеКлючи", СериализуемыеКлючи); + + ОписаниеСвойств.Добавить(ОписаниеСвойства); + + КонецЦикла; + + КэшСвойствТипов.Вставить(Тип, ОписаниеСвойств); + + Возврат ОписаниеСвойств; + +КонецФункции + +Процедура ПрочитатьДополнительныеПоля(Объект, Результат) + + Тип = ТипЗнч(Объект); + + ОписанияГеттеров = КэшГеттеровСвойств[Тип]; + Если ОписанияГеттеров = Неопределено Тогда + ОписанияГеттеров = ПрочитатьГеттерыСвойствТипа(Тип); + КонецЕсли; + + Для Каждого ОписаниеГеттера Из ОписанияГеттеров Цикл + + ЗначениеСвойства = Рефлектор.ВызватьМетод(Объект, ОписаниеГеттера.ИмяМетода); + ЗначениеСвойства = ПреобразоватьОбъектСериализации(ЗначениеСвойства); + Если ОписаниеГеттера.Обязательное ИЛИ ЗначениеСвойства <> Неопределено Тогда + Результат.Вставить(ОписаниеГеттера.ИмяСвойства, ЗначениеСвойства); КонецЕсли; КонецЦикла; КонецПроцедуры -Процедура ПрочитатьДополнительныеПоля(Объект, Результат) +Функция ПрочитатьГеттерыСвойствТипа(Тип) - ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(ТипЗнч(Объект)); + ОписанияГеттеров = Новый Массив(); + + ТаблицаМетодов = Рефлектор.ПолучитьТаблицуМетодов(Тип); Для Каждого СвойстваМетода Из ТаблицаМетодов Цикл @@ -298,15 +408,20 @@ Обязательное = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(АннотацияСериализуемое, "Обязательное", Ложь); - ЗначениеСвойства = Рефлектор.ВызватьМетод(Объект, СвойстваМетода.Имя); - ЗначениеСвойства = ПреобразоватьОбъектСериализации(ЗначениеСвойства); - Если Обязательное ИЛИ ЗначениеСвойства <> Неопределено Тогда - Результат.Вставить(ИмяСвойства, ЗначениеСвойства); - КонецЕсли; + ОписаниеГеттера = Новый Структура(); + ОписаниеГеттера.Вставить("ИмяМетода", СвойстваМетода.Имя); + ОписаниеГеттера.Вставить("ИмяСвойства", ИмяСвойства); + ОписаниеГеттера.Вставить("Обязательное", Обязательное); + + ОписанияГеттеров.Добавить(ОписаниеГеттера); КонецЦикла; -КонецПроцедуры + КэшГеттеровСвойств[Тип] = ОписанияГеттеров; + + Возврат ОписанияГеттеров; + +КонецФункции Функция ПолучитьСериализуемыеКлючи(СвойствоОбъекта) diff --git "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\241\321\202\320\260\321\202\320\270\321\201\321\202\320\270\320\272\320\260\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\260.os" "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\241\321\202\320\260\321\202\320\270\321\201\321\202\320\270\320\272\320\260\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\260.os" index dab8f46..180c5e0 100644 --- "a/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\241\321\202\320\260\321\202\320\270\321\201\321\202\320\270\320\272\320\260\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\260.os" +++ "b/src/BenchmarkOneScript/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\241\321\202\320\260\321\202\320\270\321\201\321\202\320\270\320\272\320\260\320\221\320\265\320\275\321\207\320\274\320\260\321\200\320\272\320\260.os" @@ -86,7 +86,7 @@ Если Не Замеры = Неопределено Тогда Прочитать(Замеры); КонецЕсли; - + КонецПроцедуры Процедура ОбработкаПолученияПредставления(Значение, СтандартнаяОбработка) @@ -220,11 +220,8 @@ Иначе ВызватьИсключение СтрШаблон("Замеры с типом %1 не поддерживаются", ТипЗнч(Замеры)); КонецЕсли; - - _УпорядоченныеЗамерыВремени = ПроцессорыКоллекций.ИзКоллекции(_ЗамерыВремени) - .Сортировать() - .ВМассив(); + ЗаполнитьУпорядоченныеЗамерыВремени(); Рассчитать(); Возврат ЭтотОбъект; @@ -267,7 +264,7 @@ // Возвращаемое значение: // СтатистикаБенчмарка Функция Разделить(Статистика) Экспорт - + ЗамерыВремени = Math.Разделить(_ЗамерыВремени, Статистика.ЗамерыВремени()); ЗамерыПамяти = Math.Разделить(_ЗамерыПамяти, Статистика.ЗамерыПамяти()); @@ -392,4 +389,14 @@ КонецФункции +Процедура ЗаполнитьУпорядоченныеЗамерыВремени() + + СписокЗначений = Новый СписокЗначений(); + СписокЗначений.ЗагрузитьЗначения(_ЗамерыВремени); + СписокЗначений.СортироватьПоЗначению(); + + _УпорядоченныеЗамерыВремени = СписокЗначений.ВыгрузитьЗначения(); + +КонецПроцедуры + #КонецОбласти \ No newline at end of file