( Обновление : Полная поддержка агрегирования ORM теперь включена в Django 1.1. Верный для ниже предупреждения об использовании частных API, метод, зарегистрированный здесь больше, не работает в пост1.1 версиях Django. Я не закопал для выяснения почему; если Вы находитесь на 1,1, или позже необходимо использовать реальное агрегирование API так или иначе.)
базовая поддержка агрегирования уже была там в 1,0; это просто не документировано, не поддерживается, и еще не имеет дружественного API сверху его. Но вот то, как можно использовать его так или иначе, пока 1.1 не прибывает (на Ваш собственный риск, и в полном знании, что атрибут запроса group_by не является частью общедоступного API и мог измениться):
query_set = Item.objects.extra(select={'count': 'count(1)'},
order_by=['-count']).values('count', 'category')
query_set.query.group_by = ['category_id']
, Если Вы тогда выполняете итерации по query_set, каждое возвращенное значение будет словарем с ключом "категории" и ключом "количества".
Вы не должны заказывать - количество здесь, это просто включено, чтобы продемонстрировать, как оно сделало (оно должно быть сделано в .extra () вызов, не в другом месте в queryset цепочке конструкции). Кроме того, Вы могли точно также сказать количество (идентификатор) вместо количества (1), но последний может быть более эффективным.
Примечание также, что при установке .query.group_by, значения должны быть фактическими именами столбцов DB ('category_id') не имена полей Django ('категория'). Это вызвано тем, что Вы настраиваете внутренности запроса на уровне, где все находится в терминах DB, не условиях Django.
Не полный ответ, у меня просто нет времени на подробные тесты, которые нужны вашему вопросу, но, надеюсь, они будут полезны.
Вы нацелены на комбинацию JVM (по сути, JIT) и базовая подсистема ЦП / памяти. Таким образом, фраза «Это быстрее на JVM X» вряд ли будет правильным во всех случаях, поскольку вы переходите к более агрессивной оптимизации.
Если ваш целевой рынок / приложение будет в основном работать на определенной архитектуре, вам следует подумать об инвестировании в инструменты, специфичные для Это. * Если ваша производительность на x86 является критическим фактором, то Intel VTune отлично подходит для детализации описанного вами вида jit output analysis . * Различия между 64-битными и 32-битными JIT могут быть значительными, особенно на платформах x86, где соглашения о вызовах могут изменяться и возможности регистрации сильно различаются.
Вероятно, вы захотите чтобы получить профилировщик выборки. Накладные расходы на инструменты (и связанный с этим удар по таким вещам, как встраивание, загрязнение кеша и увеличение размера кода) для ваших конкретных потребностей были бы слишком большими. Анализатор Intel VTune действительно может использоваться для Java, хотя интеграция не такая тесная, как другие.
Если вы используете Sun JVM и счастливы только тем, что знаете, что делает последняя / самая лучшая версия, тогда параметры, доступные для , для исследования вывода JIT значительны, если вы немного разбираетесь в ассемблере.
В этой статье подробно рассказывается о некоторых интересных анализах с использованием этой функциональности.
История изменений История изменений показывает, что предыдущая встроенная сборка на самом деле была контрпродуктивной и позволяла компилятору полностью контролировать вывод (с настройками в коде , а не с директивами в сборке) дал лучшие результаты.
Поскольку LZF в эффективной неуправляемой реализации на современных настольных процессорах CPUS в значительной степени ограничен пропускной способностью памяти ( следовательно, он конкурирует со скоростью неоптимизированного memcpy) вам понадобится код, чтобы полностью оставаться в кэше уровня 1.
Таким образом, любые статические поля, которые вы не можете преобразовать в константы, должны быть помещены в один и тот же класс, поскольку эти значения часто будут помещаться в одну и ту же область памяти, выделенную для vtables и метаданных, связанных с классами.
Распределение объектов, которые не могут быть перехвачены by Escape Analysis (только в версии 1.6 и выше) необходимо избегать.
Код c агрессивно использует развертывание цикла. Однако производительность этого на старых (эпоха 1.4) виртуальных машинах сильно зависит от режима, в котором находится JVM . По-видимому, последние версии sun jvm более агрессивны при встраивании и развертывании, особенно в серверном режиме.
Инструкции предварительной выборки, сгенерированные JIT, могут иметь большое значение для кода, подобного этому, который близок к ограничению памяти.
Ваша цель движется, и продолжу. Опять же, предыдущий опыт Марка Леманна:
размер HLOG по умолчанию теперь равен 15 (кеши процессора увеличены)
Даже незначительные обновления jvm могут включать значительные изменения компилятора
6544668 Операции с массивами, которые могут не выравниваются во время выполнения. 6536652 Реализовать оптимизацию сверхслова (SIMD) 6531696 не использовать немедленное сохранение 16-битных значений в памяти на процессоре Intel 6468290 Разделение и распределение вне eden на основе процессора
Измерение, измерение, измерение. ЕСЛИ вы можете заставить свою библиотеку включать (в отдельной dll) простой и легкий в выполнении тестовый тест, который регистрирует соответствующую информацию (версия vm, процессор, ОС, параметры командной строки и т. Д.) И упрощает отправку вам обратно. увеличьте охват, лучше всего вы будете покрывать тех людей, которые заботятся о нем.
Что касается исключения проверки границ , я полагаю, что новый JDK уже будет включать улучшенный алгоритм, который устраняет его, когда это возможно. Это две основные статьи по этой теме:
Есть также эта запись в блоге, в которой поверхностно обсуждается одна из статей, а также представлены некоторые результаты сравнительного анализа не только для массивов, но и для арифметики в новом JDK. Комментарии к записи в блоге тоже очень интересные, поскольку авторы вышеуказанных статей представляют очень интересные комментарии и обсуждают аргументы. Кроме того, есть несколько указателей на другие похожие сообщения в блогах по этой теме.
Надеюсь, это поможет.
It's rather unlikely that you need to help the JIT compiler much with optimizing a straightforward number crunching algorithm like LZW. ShuggyCoUk mentioned this, but I think it deserves extra attention:
The cache-friendliness of your code will be a big factor.
You have to reduce the size of your woking set and improve data access locality as much as possible. You mention "packing bytes into ints for performance". This sounds like using ints to hold byte values in order to have them word-aligned. Don't do that! The increased data set size will outweigh any gains (I once converted some ECC number crunching code from int[] to byte[] and got a 2x speed-up).
On the off chance that you don't know this: if you need to treat some data as both bytes and ints, you don't have to shift and |-mask it - use ByteBuffer.asIntBuffer()
and related methods.
With current 1.6 JVM, how many элементы должны быть скопированы перед System.arraycopy превосходит цикл копирования?
Лучше провести тест самостоятельно. Когда я делал это еще в Java 1.3 раза, это было где-то около 2000 элементов.
На данный момент ответов много, но есть пара дополнительных вещей:
Реализация H2 также была немного оптимизирована (например: она больше не очищает хэш-массив, это часто имеет смысл); и я действительно помог изменить его для использования в другом проекте Java. Мой вклад в основном состоял в том, чтобы изменить его, чтобы он был более оптимальным для случая без потоковой передачи, но это не коснулось жестких циклов кодирования / декодирования.
но поскольку JVM ДОЛЖНА очищать пространство.Реализация H2 также была немного оптимизирована (например: она больше не очищает хэш-массив, это часто имеет смысл); и я действительно помог изменить его для использования в другом проекте Java. Мой вклад в основном состоял в том, чтобы изменить его, чтобы он был более оптимальным для случая без потоковой передачи, но это не коснулось жестких циклов кодирования / декодирования.
но поскольку JVM ДОЛЖНА очищать пространство.Реализация H2 также была немного оптимизирована (например: она больше не очищает хэш-массив, это часто имеет смысл); и я действительно помог изменить его для использования в другом проекте Java. Мой вклад в основном состоял в том, чтобы изменить его, чтобы он был более оптимальным для случая без потоковой передачи, но это не коснулось жестких циклов кодирования / декодирования.