Видимо я не вполне ясно выразил свою мысль. Цель была не посчитать конкретно сколько изолированно занимает каждый вызов, а оценить поведение in the wild.
То есть так, как это будет выглядеть в реальной программе, когда jit развернет циклы и заинлайнит библиотечные методы.
Если мерять абсолютные показатели — то да.
Но в данном случае меряется производительность Trove варианта относительно jdk. В обоих случаях jvm позволено вносить любые оптимизации (и они будут примерно одинаковы — unroll + inline). Ассемблерный листинг это подтверждает.
По поводу States — это средство для per-thread/per-benchmark переменных в многопотоковых бенчмарках (для удобства).
По поводу Loops — я не тестирую свои методы, я тестирую методы библиотеки, и как бы не был сделан unrolling тестирующего метода, кол-во вызовов библиотечного метода от этого не изменится.
Если мы говорим о списках — элементы хранятся в массивах int[] для TIntArrayList, long[] для TLongArrayList. При добавлении элемента, в случае если в массиве нет места, будет создан новый массив, большего размера. Старый подберет GC. В случае массового добавления элементов он даже Eden Space покинуть не успеет.
Весьма спорное утверждение. Возьмем суммирование ряда — какая разница сколько элементов нужно просуммировать. И вполне возможно, что заранее неизвестно сколько элементов в ряду.
Установка AutoBoxCacheMax при включенном AggressiveOpts работает. Дело в том что создание объекта в Java — очень быстрая операция, поэтому и разница невелика. А GC работает в параллельном потоке и поскольку памяти хватает Full GC и STW не случается.
-Djava.lang.Integer.IntegerCache.high=N не выключает механизм autoboxing'а полностью. Oн не создает новые объекты для Integer попадающих в промежуток (-128) — N, а возвращает ссылки на заранее сформированные объекты. Ключ -XX:+AggressiveOpts поднимает N до 20000, так что тест с 1тыс уже с «выключенным» autoboxing'ом
страницы на разогретом кеше и с нагрузкой в 100 конкурентных соединений отдаются за 20-30мс
Отличный результат.
Правильно ли я понимаю, что система заточена под запросы типа «Найди отель в Уганде, с шахматным клубом и поэтессами», а не на «найди мне double на 2 недели за $500 все равно где»?
Нельзя ли привести ТТХ комплекса, на котором работает Mongo, максимальный достигнутый RPS и примерное кол-во записей об отелях? И какая СУБД используется как основная?
Да, преобразование происходит каждый раз. Расчет на то, что расходы на преобразования перекрываются бонусом от быстрого написания. Естественно, для достижения большой пропускной способности лучше писать на Java.
> И ещё: можно ли болты выстраивать в цепочку, направляя данные с одного на другой?
Да, в последнем примере CalcApp так и сделано Spout->ClientIdBolt->RaterBolt->PrintOutBolt.
Про методы защиты. Это не 100% защита, а способ затруднить доступ. Одно дело сделать select * и унести распечатку, и совсем другое сидеть и угадывать. При этом угадывать можно только на той же базе, нельзя унести замаскированное и на другой системе пытаться восстановить информацию.
FGA (fine grained audit) позволяет отслеживать select'ы по колонке, да еще и с анализом условий запроса. Не в этом дело. Обеспечение безопасности — это многоступенчатый процесс. Эта фича рассматривается как «дешевый» (в смысле ресурсов) вариант. Для усиленной защиты существует Transparent data encryption, когда данные хранятся в зашифрованном виде. Но естественно и ресурсов на encrypt/decrypt уходит существенно больше.
То есть так, как это будет выглядеть в реальной программе, когда jit развернет циклы и заинлайнит библиотечные методы.
Но в данном случае меряется производительность Trove варианта относительно jdk. В обоих случаях jvm позволено вносить любые оптимизации (и они будут примерно одинаковы — unroll + inline). Ассемблерный листинг это подтверждает.
loop без unrolling'a:
loop с unrolling'om (грубо):
По поводу Loops — я не тестирую свои методы, я тестирую методы библиотеки, и как бы не был сделан unrolling тестирующего метода, кол-во вызовов библиотечного метода от этого не изменится.
Если хочется inplace обработки — то forEach
Jdk traverse 774 op/s, Trove traverse 3548 op/s. Вы видимо в колонку Mean error посмотрели. Кол-во операций в секунду в колонке Mean.
По сути списки Trove — не более чем удобная обертка вокруг массивов примитивов.
Установка AutoBoxCacheMax при включенном AggressiveOpts работает. Дело в том что создание объекта в Java — очень быстрая операция, поэтому и разница невелика. А GC работает в параллельном потоке и поскольку памяти хватает Full GC и STW не случается.
Рузультаты на 1тыс с «включенным» autoboxing'ом:
По поводу графиков — спасибо за рекомендацию, учту на будущее.
Правильно ли я понимаю, что система заточена под запросы типа «Найди отель в Уганде, с шахматным клубом и поэтессами», а не на «найди мне double на 2 недели за $500 все равно где»?
> И ещё: можно ли болты выстраивать в цепочку, направляя данные с одного на другой?
Да, в последнем примере CalcApp так и сделано Spout->ClientIdBolt->RaterBolt->PrintOutBolt.