Здравствуйте, ·, Вы писали:
I>>Может стать, а может и не стать. Зато в С++ у тебя полный контроль — ты сам решаешь, как данных будут размещаться в памяти. Скажем, в С++ сделать эквивалент std::vector<std::string> но с локальным хранением для частного случая это дело пяти минут. ·>Не совсем пяти минут. Тебе надо будет знать о том какой у тебя граф в памяти, т.к. если поменяешь время жизни этих самых string, то трудно отследить ломающее ли это изменение.
Я ж сказал — для частного, а не общего. Когда ты знаешь что у тебя за граф, и что нужно от контейнера — решение находится довольно быстро.
I>>Мне вот надо было в дотнете делать аналогичный фокус — массив больших объектов хранить одним куском, да так что бы объект влазил в одну страницу. И ничего, справился безо всяких ужасов и приседаний. Минут 15 потратил, после того, как от профайлера получил статистику ·>Это как? Структуру что-ли использовал?
Ну да. Прикрутил структуры, генерики и все. Были объекты-списки на фиксированую длину и кучка аналогичных вещей. Кроме всего прочего я получил экономию по памяти, и поднял производительность даже в тех сценариях, где GC никак не мешал. Собтсвенно это была только одна из сделаных мною оптимизаций.
По правде, перед этим я сидел хрен знает сколько в профайлере, несколько месяцев почти безвылазно Собтсвенно, вся работа с кодом сводилась к рефакторингам — собрать нужные данные вместе, в логическую структуру, а уже та довольно быстро заменялась на генерики-структуры-вычисления.
Здравствуйте, ·, Вы писали:
I>>Числодробилка это любой алгоритм сложностью выше O(1). Сортировка, строки, массивы — эти вещи определяют производительность приложения, пропускную способность. Соответственно, их и надо полировать постоянно, а не гордиться тем, что решение менеджед. ·>В java тоже их полируют постоянно, но не на уровне исходников JDK (хотя исходники тоже полируют, но оставаясь в рамках языка), а на уровне JIT-оптимизатора.
Этого мало. В джаве эти фокусы сделаны по причине кроссплатформенности в ущерб производительности. В дотнете прямо противоположное решние. Собственно если ты запилишь простейший цикл на массиве, нативный код уже даст выигрыш. Чем сложнее логика — тем больше будет отрыв нативного решения.
Выиграть у нейтива можно только за счет смены самого алгоритма, заточить скажем версию под джыт, гц и тд, если нет проблем с локальностью. И то, на плюсах всего лишь увеличится сложность решения. Принципиально же любой менеджед супер-пупер алгоритм можно ускорить за счет нейтива.
Здравствуйте, ·, Вы писали:
I>>Сильно частный случай. Локальность плюсовых структур ни одна vm не может обставить. Разница между кешем и доступом к памяти примерно два порядка. Кое где рантаймные оптимизации компенсируют отставание, но это мелочовочка. ·>Тут надо осторожно выражаться, не так категорично. Скажем, std::vector<std::string> внезапно совсем не локальный, а char[] локальный везде. Потом — компактификация кучи и ArrayList<String> может стать локальнее, чем std::vector<std::string>.
Вообще то std::vector<std::string> может быть как раз полностью локальным, при условии что строки не слишком длинные. ) Ну а разговоры про локальность из-за компактификацию кучи — это вообще смешно. Это приблизительно тоже самое, что надеяться на то, что последовательные вызовы malloc выделят память в одной области. )))
Здравствуйте, Ikemefula, Вы писали:
_>>Ну насчёт "в ущерб" я бы не был столько уверен. А вот то, что при прочих равных предпочтут открытое, несомненно. Я собственно и сам так предпочитаю. ) I>Сам подумай — почему HPC, HFT, высоконагруженые приложения пишут на джаве, пейтоне. По уму, если выбирают перформанс, то надо писать исключительно на С++. Опаньки ! I>Теперь понятно, что если производительность отстаёт не на порядки, то это _дешевле_ пофиксить железом иногда даже виртуальным. Собтсвенно выбор в пользу джавы именно так и делается, а то бы весь софт писали бы на С++.
Так в этих твоих примерах совсем другой расклад. Там не открытость vs производительность, а "безопасное использование слабых программистов" vs производительность (у Java) или же "ускоренная разработка" vs производительность (у Питона, хотя в случае Питончика там своя специфика, т.к. там он обычно работает тонкой обёрткой вокруг C библиотек).
_>>Один процент — это было про часть веба (в котором скриптам уже тяжеловато). А так то у Java/C# естественно есть и другие области (энтерпрайзные формочки — это их родная стихия), в которых и быстродействия особого не надо и скрипты не особо наступают. I>Ога, в банках быстродействие не надо ?
В их офисном конечно не надо. Мы же не про клиринговые центры и т.п. процессинг говорим, а про "энтерпрайзные формочки". Кстати, а вот про ПО в клиринговых центрах тоже было бы интересно разузнать (скажем у Visa или MasterCard), на чём оно написано — там то как раз производительность вполне актуальна.
Здравствуйте, ·, Вы писали:
·>Нативный код это как крайний случай. Было бы классно, если бы можно было писать софт любой требуемой производительности на наиболее удобном языке.
Непонятно причём тут именно "нативный код", когда дело-то совсем не в целевом наборе инструкций, а в выразительности языка. C++ скомпилированный в JS работает быстро, как раз потому что на нём скорость хорошо выражается. Если же ты скомпилируешь Java в native — то она там будет примерно также тормозить, так как все эти косвености никуда не испарятся.
·>Но увы, удобный красивый язык может не тянуть требуемую производительность, поэтому приходится начинать писать некрасиво, а в конце концов — переходить на более близкий к железу язык.
Расскажи какие языки ты считаешь красивыми. Неужели Java?
Здравствуйте, ·, Вы писали:
·>Потом — компактификация кучи и ArrayList<String> может стать локальнее, чем std::vector<std::string>.
В случае с вектором строк — получаем элемент из вектора, и у нас уже на руках указатель на массив символов (либо и вовсе сам массив символов в случае SSO).
На Java же получив элемент из ArrayList имеем указатель на String в котором хранится указатель на массив символов — получается лишняя индерекция по построению. Только в реальности это скорее будет не массив строк, а массив объектов типа Person внутри которых строки (либо ещё несколько уровней композиции) — на Java будет дополнительная косвенность на каждый новый уровень.
Никакая компактификация эти лишние индерекции не уберёт.
Здравствуйте, Ikemefula, Вы писали:
I>Сортировка это перепахивание RAM, то есть, именно то, ради чего стоит использовать нативный код. У тебя даже тупой проход по массиву интов на сишном коде даст вопиющую разницу.
Нет, не даст — на уровне массива интов отличия как раз непринципиальные.
I>Чем сложнее алгоритм, тем больше будет эта разница.
А здесь верно.
I>Хочешь перформанс — есть только Си и тот без плюсов.
Здравствуйте, Ikemefula, Вы писали:
I>Этого мало. В джаве эти фокусы сделаны по причине кроссплатформенности в ущерб производительности. В дотнете прямо противоположное решние. Собственно если ты запилишь простейший цикл на массиве, нативный код уже даст выигрыш. Чем сложнее логика — тем больше будет отрыв нативного решения.
Ты судишь по отчётам о супероптимизациях каких-нибудь memcpy за счёт фишек конкретного набора инструкций?
Если так, то у JIT как раз больше шансов сделать тут оптимизацию под конкретный случай — это раз. И, чем дальше отличается задача от мейнстрима вбивания инструкций в конвейеры процессора — тем менее важна вылизанность нативности. На партиционировании в quicksort слишком много сравнений, чтобы нативность что-то дала.
А дальше уже начинает играть роль алгоритмическая оптимизация — например, в Java quicksort partitioning это dual-pivot, а в GCC STL — introsort с выбором по тупой медиане и неуправляемой левосторонней рекурсией, соответственно, свалиться в плохой случай ей в разы легче.
I>Выиграть у нейтива можно только за счет смены самого алгоритма, заточить скажем версию под джыт, гц и тд,
Dual pivot не имеет никакой связи с JIT или GC
I> если нет проблем с локальностью. И то, на плюсах всего лишь увеличится сложность решения. Принципиально же любой менеджед супер-пупер алгоритм можно ускорить за счет нейтива.
И опять ты игнорируеш важность оптимизации в рантайме.
Здравствуйте, Ikemefula, Вы писали:
I>·>Правильно — _никакой манаджед_. Но у нас другой случай: возьмём sort — почему один манаджед даёт внятный перформанс, а другой — не даёт?
I>Это враньё. Сортировка это перепахивание RAM, то есть, именно то, ради чего стоит использовать нативный код.
"Это враньё" ((c) Ikemefula). Перепахиванию RAM пофиг нативность кода, до тех пор, пока интерпретатор хоть как-то разумен — даже самый тупой JIT тут даёт достаточный результат.
I> У тебя даже тупой проход по массиву интов на сишном коде даст вопиющую разницу.
Не даст.
I>В джаве такие вещи сделали менеджед исключительно из за кроссплатформенности и в ущерб производительности. В дотнете никто про кроссплатформенность, по честному, не думал.
Да, но это проявляется совсем в других местах — считаем, в специфике представления об ОС.
I>Если речь про перформанс, то он обязан быть самым лучшим, а не просто внятным. У джавы перформанс никогда не был на первом месте. У ней на первом месте кроссплатформенность, менеджед со своими плюшками. Все что угодно, но не перформанс. I>Хочешь перформанс — есть только Си и тот без плюсов.
С чего это без плюсов? Многие вещи, наоборот, с плюсами сильно лучше. Например, для той же сортировки инстанциирование компаратора вместо вызова функции по указателю может сильно ускорить алгоритм.
Были утечки в третьесторонней либе по её же вине.
Собсно, популярные утечки в современном нейтиве — это неразрушенные данные TLS. Т.е. некие данные однократного/статического характера.
Это болезнь многих системмных либ (open SSL, например).
Почему порой бывает так — отдельный разговор.
В дотнете и джаве может происходить аналогичное, кста, при каком-нить thread abort.
·>К неинициализированнй/освобождённой памяти не обращались? И segfault-ы не падали?
В биржевой проге?
·>В каком ещё "динамическом" коде? javascript что-ли? Причём тут вообще динамический код?
Джавовский код весьма динамичный. Сплошные приведения типов и все как один — динамические.
·>Тебя куда-то заносит постоянно. Вначале в dotnet vs java запихал native, а теперь ещё и динамику.
Курить, что есть динамика.
V>>Я еще ни разу не видел, чтобы под Джаву писали в 10 раз больше тестов, чем исходного кода. ·>Из-за того, что у тебя проблемы со зрением, не значит, что их нигде не пишут. ·>Тем более лишь только потому что это джава. Или ты возьмёшься утверждать, что все написанные С++-системы имеют 10х объём тестов?
В С++ надо примерно 2x, в джаве примерно 20x.
Потому что уровень типизации исходника несопоставим от слова совсем.
Там, где в джава разруливается на рантайм-полиморфизме и динамическом приведении, там в 90% на С++ идёт статическая диспетчеризация, а не рантайм. Соответственно, нет "рантайм" — не надо ЭТИ моменты тестировать запуском на исполнение, их тестирует сам факт компиллируемости. Иначе это будет тест компилятора, а не программы, ы-ы-ы.
V>>А это вообще минимальная граница, с которой только можно начинать хоть как-то полагаться на тестирование. На типичные джавовские юнит-тесты без слёз не взглянешь. ·>Давай я напишу слёзогонные тесты на Плюсах, это улучшит Джаву в твоих глазах?
Нет конечно. Что еще можно ожидать от мира Джавы? ))
Дело не в этом. "Без слёз" — это по логике самого тестирования. Тест должен тестировать вообще все ветки прохождения кода из исходника, а в джаве этих веток слишком много на ровном месте, по меркам того же С++, из-за слабой типизации. У нас тесты покрывают 100% веток, в джаве я и 50% покрытия НИ РАЗУ за всю свою жизнь не видел. И, если ты мне пришлешь свой код и тесты к нему под DNA — и не увижу, ес-но. )) Я свой код и тесты могу прислать, кста. Ну что ченж?
·>Кстати, скажи тем, кто пишет слезогонные тесты, чтобы они их писали получше, если чё — скажешь, что я разрешил.
Да ты сам научись, для начала. Потом ужаснись и беги оттуда, беги. ))
V>>·>А в нетривиальных случаях, когда RangeCheckElimination ниасиливает — человеку тоже асилить непросто. Хотя да, ведь зачем напрягать компьютер, девушки С++-сники хорошо справляются. V>>Открой для себя т.н. "алгоритмы" буста и STL. Прекрасно компьютер справляется. Просто JIT-у некогда справляться, в отличие от полноценного оптимизатора С++. ·>Доказательства есть?
Того, что оптимизатор C++ круче оптимизатора JIT?
В школу срочно!
V>>>>>>Там всей разницы, что у тебя при этом никаких проверок, а в контейнерах, таки, итератор сравнивают на end(). V>>>>·>В каких? Кто сравнивает? std::vector — не сравнивает. V>>Алгоритмы сравнивают: ·>Не понимаю чем это будет принципиально отличаться от java.
В плане безопасности такого кода? — ничем.
О чем и речь, собсно.
Чтобы выйти за пределы диапазона vector, его надо дёргать ручками.
Но любое такое "дергание" — это какой-то алгоритм.
В С++ принято оформлять телодвижение в пересчете на элемент, а пробегаться по коллекциям через подходящие т.н. "алгоритмы".
В дотнете для таких вещей есть расширения коллекций System.Linq, чтобы ручками по ним не бегать.
Конечно, можно ручками и в дотнете бегать и в С++ и получать ошибки и там и там, но есть правила хорошего тона.
V>>>>Дык, уровень косвенности на единицу меньше. V>>·>Расшифруй. V>>Ы? ·>Я не понял твоё высказывание. косвенность чего? Почему на единицу, а не на 0.99 или 42?
Не понял, так не понял.
Я не удивлён.
V>>>>90% кода типичной HFT-системы не требует вообще ничего из того, что дают управляемые среды. ·>>>Неправда. Скажем, в HFT-системе может быть несколько web-интерфейсов, работа с субд, гейты с разными WebService/Rest. А ещё, скажем, может быть инфраструктура мониторинга, тестирования, деплоймента и т.п. Ты правда считаешь, что native для этого лучше, чем managed?? V>>Конечно. V>>В реалтайме идёт заливка в файл в транзакционную файловую систему, ·>FileOutputStream.write?
Да пофиг на конкретное АПИ.
Я отвечал на то, что в HFT, видите ли, идёт обращение к БД и веб-сервисам и поэтому джава удобней. ))
V>>а не в БД. Там никакая БД не справится, ес-но. ·>Смотря где.
В реальном HFT.
·>Вести бд счетов, движение средств, и контактные и прочие данные клиентов. Архивы трейдов. Описание инструментов.
30-40 таблиц, я же давал тебе цифры уже.
·>Ты уверен, что это всё требует реалтаймную заливку в транзакционную фс?
Я уверен, что такая размерность задачи не требует никакой джавы от слова совсем. ))
Такую "сложность" сейчас делают студенты на коленке на чем угодно.
Это уровень ноль современного программирования, о чем речь вообще?
Любой захудалый интернетный магазин на порядок сложнее.
А их (магазины) делают конторы из 3-5-ти студентов.
Это не сравнить с затратами на организацию биржи.
Т.е., попытка сэкономить 0.00001% от всех затрат, взяв джаву как инструмент, это смешно. ))
V>>Ес-но это всё происходит через нейтив. Периодически в БД сливают только снапшоты. Это другой процесс/узел, ему надо проводить бешеную агрегацию исходных данных, там ничего кроме нейтива не выживает. Инфраструктура мониторинга так и работает, как отдельный узел, куда в бешеном режиме сливаются вообще все данные и на этом узле обычно и происходит та самая суровая агрегация и потом неторопливая выдача данных по запросам в XML или другом текстовом формате. В том числе клиентам на Джаве, ес-но. ·>А почему таки на Джаве? Писали бы уж всё на плюсах, ведь там Алгоритмы есть.
Потому что вес клиента и вес биржи несопоставимы. Клиентами бывают совсем маленькие брокерские конторы. Ну и ОК.
V>>Инфраструктура тестирования/сертифицирования, все эти эмуляторы — это нейтивное АПИ с выходом на скрипт, там нечего делать никакой джаве, потому что требуется работать БЕЗ развернутых ср-в разработки, т.е. подправил скрипт — тут же запустил. ·>А какие средства разработки надо разворачивать для Явы? Ну там git скачать, чтобы исходники из репо забрать и.... ну можно ещё Идею поставить, чтобы подправлять "скрипты" пришлось не в тупом notepad, а с автодоплнениями и подсказками. Собственно всё.
Вот этого всего и даром не надо и гонится ссаными вениками.
Оператор на целевой машине всегда удалённо работает.
V>>Деплойментом тоже обычно занимаются скриптовые утилиты (сейчас их много, в т.ч. писаных на руби), джавовские тут самые неуниверсальные, хорошо работают только для экосистемы джавы, а не гетерогенность сценария. ·>Т.е. создать гетерогенную среду, месиво из кучи технологий, и потом начать радоваться тому, что оно всё какое-то неуниверсальное.
Это джава неуниверсальная. Всё остальное универсальное и неплохо в связке с друг другом работает.
И всё давно уже разработано, выбор ср-в просто огромен.
V>>Кароч, добро пожаловать в реальный мир, Нео. )) ·>Мир настоящих комсомольцев!
Тебя никто не держит в твоём замкнутом мирке, кроме собственного страха.
Смелее!
V>>>>А вот 90% кода действительно сложной учётной системы — уже требуют, ес-но. V>>·>Верно. Но обратное-то не верно. Бывают и не сложные системы, которые тоже могут быть требовать. V>>Ну вот ты снова спутал необходимое с достаточным и проиграл. )) ·>Это ты спутал. Не обязательно иметь "действительно" сложную систему, чтобы в ней потребовалась java с целью минимизировации затрат на разработку и поддержку.
Обязательно. Иначе дороговизна джавы по всем своим зависимостям (ср-ва разработки + инфраструктура) — это чистой воды суровый убыток.
И не надо мне про Джаву в блокноте. На ней в блокноте писать невозможно от слова совсем, это будет идиотизм, а не разработка.
V>>Увы, в плане доступа к БД ничего круче Hibernate джава-сообщество до сих пор не родило, остальное — это более простые ORM-мапперы. Кароч, тут в джаве творится сплошное позорище какое-то. В плюсах давно есть намного более мощные, чем Hibernate системы. Ну т.е. действительно на порядки более мощные и удобные. А уж более простых мапперов/хелперов — как собак нерезанных. ·>Не в курсе. А что там нового?
Нового? ))
Да это "новое" льется широкой полноводной рекой нон-стоп.
Тема настолько обширна и настолько разнообразна по своим подходам, что тут лучше самому по гуглу, а здесь спрашивать лишь непонятные моменты.
Могу лишь указать основные два направления оперирования метаинформацией для С++:
1. Ручное перечисление полей для сериализации. Часто берут boost::serialization и просто подставляют ему свой "архив". Или вот: https://github.com/the-alien/metacpp/blob/master/test/SqlTest.cpp
По ссылке библиотека биндинга на JS, но этот биндинг — это биндинг метаинформации, задешево еще и SQL прикрутили. ))
2. Всевозможные кодогенераторы, которые генерят акцессоры к объектам по примерно вот такому валидному (полезному) С++ исходнику:
#pragma db object
class person
{
...
private:
friend class odb::access;
person () {}
#pragma db id
string email_;
string name_;
unsigned short age_;
};
·>Универсальный коннектор сделали наконец-то по типу jdbc?
У меня рука уже устала ко лбу её прикладывать. ))
Интересно, на какую букву заменить первую в "jdbc", чтобы получить нечто, что на 20 лет старше самой джавы? ))
И да, вот еще интересно. Я вот видел некие провайдеры jdbc, писанные как JNI-обертки не напомнишь над чем? (рука-лицо снова)
Причем, это всё г-но мамонта, ес-но, есть и более новые стандарты.
V>>А если взять дотнетный linq, то про джаву вообще вспоминать стыдно. ·>Да много всякого уже напридумывали, честно говоря не слежу за этим. Ещё и другие jvm языки есть, в scala вроде аналог линка.
В Скале нет аналога Linq, но ср-ва композиции алгоритмов не уступают как минимум С++, есть такое.
Скала — это язык с хорошей исходной концепцией, но сильно загрязнённый артефактами вынужденной интероперабельности с джава-машинкой.
Собсно, к F# аналогичные претензии.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, ·, Вы писали:
I>Может стать, а может и не стать. Зато в С++ у тебя полный контроль — ты сам решаешь, как данных будут размещаться в памяти. Скажем, в С++ сделать эквивалент std::vector<std::string> но с локальным хранением для частного случая это дело пяти минут.
Честно говоря, это до тех пор, пока не надо работать с методом, который хочет именно std::string. А таких полно. Сделать абстрактный интерфейс (в смысле Java) readonly строки с фиксированным набором методов и требовать в таких методах реализацию такого интерфейса — не додумались, или не успели, неважно, но цена конверсии из своей строки в стандартную может быть слишком высокой.
Здравствуйте, Ikemefula, Вы писали:
I>>>Никакого противоречия. JIT это всего лишь компенсация. Ни один распрекрасных джыт не может в общем случае обогнать хороший плюсовый компилер. Нет у него столько времени. N>>Зато у него есть данные о реальном поведении приложения, и они часто оказываются важнее. N>>Причём даже по сравнением с PGO, если PGO не может выбрать между несколькими типичными профилями, или тестовая нагрузка не соответствует реальной. I>В некоторых задачах, когда нет нагрузки на память или локальность обеспечили вручную, это поможет, да.
Не обязательно память. Дёрганый из-за слишком большого количества сравнений и развилок алгоритм — и его частная реализация для случая, когда реально используется 1/5 от всего кода, а частные случаи не происходят. Именно в алгоритмической тематике такого дофига, да и в управляющей — немало.
N>>>>Но в теме HFT, которую обсуждает твой оппонент, это всё как раз мало значимо, и в сортировке — тоже. I>>>Ему не нравится сам факт наличия нативного кода в дотнете. N>>Ему не нравится, что сравнивают реализации с нативным кодом против чисто VMовских. I>А по моему он не понимает аргумент про закрытые и открытые технологии.
А что тут закрытого-то? Любимый vdimas’ом C++/CLI?
N>>Спасибо за рассказ, я про Rotor впервые тут услышал. Но если речь идёт всего лишь об открытой версии дотнета — преимущества этих подходов видны на основных целевых задачах дотнета, но не HFT или чём-то другом столь же специализированном.
I>Еще раз — дотнет до недавних пор был прибит гвоздями к винде.
Чиво? Mono, Unity3D — уже много лет как. Да, это малая часть, но как раз соответственно обсуждаемому тут основному движку.
I> Следовательно, без винды ты никак его использовать не можешь. Следовательно, в HFT будут видны проблемы не только дотнета, но и винды.
Если бы дотнет был так выгоднее для HFT сам по себе — было бы полно реализаций на Mono вместо Java. Mono никогда не имел необходимости затачиваться под винду и ограничиваться виндой (хотя идиотизм, зашитый в стандарты, подбил и его).
I>С учетом того, что винда сама имеет проблемы с LL, удивляться нечему. Задержка в 1мс на винде может спокойно дать и 15 секунд ожидания и это никак не исправить ни дотнетом, ни эрлангом, ни чем угодно. Это особенность ядра винды, планировщика и её работы с железом. I>Потому в своём уме винду крайне редко пускают в реалтайм-приложения. Соответственно дотнет пилить, оптимизировать под HFT смысла большого нет. Чего и наблюдаем.
Java тоже не имеет HFT основной тематикой. Тем не менее делают целевые VM вроде того же Azul.
Но и основные реализации тоже тюнят — посмотри доклады народа из "Одноклассников" в стиле "с C1 мы имеем тормоза менее 200 мс, для наших задач это безусловно good enough".
Это за прошлое они там беспокоятся. Java EE не нужен, сервера приложений не нужны, спринг бут удобнее в разы. Servlet API допилить разве что немного для поддержки реактивности.
Здравствуйте, Ikemefula, Вы писали:
I>>>Проверяем. Прогрей GC так, что бы миллиард объектов работал гладко, без проблем с GC. Естетсвенно, не прибегая ко всями пулам и off-heap Решениям. N>>Про не прибегая к offheap это подтасовка. Я как раз говорил, что offheap — один из методов решения. I>Я тебя попросил показать _другой_ способ для этой же задачи. Например — твой прогрев.
Вообще-то и он реально работает — после того, как прогрев сделан, и принудительный GC выполнен, отсутствие последующих аллокаций приводит к тому, что GC не запускается в течение всего времени работы биржи. Самое сложное было таки устранить все аллокации даже не выходящие за пределы 0-го поколения — вот тут пришлось доработать offheap’ом. Плохо то, что результат некрасивый внутри, но он есть
А твой каприз я таки проигнорирую — он не соответствует обсуждаемой в субтреде тематике.
I>>>Когда я пишу "по максимуму" я говорю про частоту вызовов и суммарные временные издержки. N>>Для задач типа HFT важна равномерность задержек, даже если в сумме их будет больше. А это легко обеспечить инкрементальным GC, что и делают соответствующие VM. I>Суммарно это совсем не обязательно за всё время работы приложения
Это совершенно неконкретные слова. Realtime определяется через статистические характеристики времени реакции. Например, "95% до 20мкс, 99% до 50мкс, 100% до 10мс". Для HFT, в отличие от баек кое-каких третьих лиц в данной теме, не обязательно 100% в минимальных пределах; нет, даже если всего лишь 50%, но быстрее всех конкурентов, это может дать устойчивый плюс на хлеб с колбасой. Максимальные цифры тут скорее психологически важны, чем практически. Но устойчивость средних характеристик помогает значительно более простому анализу всей системы, а вот это таки крайне важно.
Очевидно же фейк
* кококо должно быть с большой буквы
* жаба господа используют vim
* жава господа оперируют круглыми числами, числа типа 85 их интересуют
Здравствуйте, vdimas, Вы писали:
V>Дело не в этом. "Без слёз" — это по логике самого тестирования. Тест должен тестировать вообще все ветки прохождения кода из исходника, а в джаве этих веток слишком много на ровном месте, по меркам того же С++, из-за слабой типизации. У нас тесты покрывают 100% веток, в джаве я и 50% покрытия НИ РАЗУ за всю свою жизнь не видел.
Хм, у меня народ и на Java и на Python покрывал >85% (а больше и не было реально нужно, за 100% покрытием не гнались). По-моему, тебе надо кого-то уволить ну или самому
V>·>Доказательства есть? V>Того, что оптимизатор C++ круче оптимизатора JIT? V>В школу срочно!
Со словом "круче" — точно в школу, там научат современному жаргону, а не старперскому.
Хотя это не отменит того, что за "круче" не стоит никакой конкретики.
А, знаю. У него на странице с описанием есть красненькая полосочка. Угадал?
Здравствуйте, Ikemefula, Вы писали:
I>Ты сам спросил а я тебе рассказал про string и array. В дотнете полно таких оптимизаций и это одна из проблем. Оптимизации вполне обоснованы — сишный компилер при ряде условий может выдать и на порядок лучший результат, нежели самый лучший менеджед код.
Именно что "при ряде условий". Проблемка в том, что эти условия обычно не воспроизводятся в реальности.
А вот JIT бьёт именно на то, что оказывается важнее всего в реале, например:
1. Устранение всех лишних проверок. Не просто написать код, чтобы процессор по умолчанию какой-то переход считал unlikely, такое и в C делается влёт (особенно с хелперами типа __builtin_expect), а вообще устранить развилку.
У Куксенко был показательный пример: в коде надо проверять if (x != null), и до прогрева null ни разу не встретился — JIT делает использование x безусловным, а на не случившийся до того вариант null — проверка заложена в хэндлере SIGSEGV.
В C++ это нереализуемо — какая-то проверка стоит на десятом уровне косвенности в шаблонах
2. Развиртуализация. У некоторого интерфейса встречаются всего 2-3 класса реализации, причём один чаще всего — в JIT версии вызова виртуального метода делается проверка базового класса (причём удешевлённая) и вызов по уже известному адресу.
3. Оптимальность не под средний по больнице процессор на момент выхода программы, а под конкретный. И не надо говорить, что JIT не успеет такое — см. хотя бы генератор LLVM из IR, он вполне быстрый, а эти методы в отрасли известны задолго до LLVM.
I>Джависты в таком случае пишут на джаве и говорят "ну и что что медленнее, зато на джаве !!!"
Здравствуйте, ·, Вы писали:
·>Можно и так, запускай ART-конверсию на серваке... Но непонятно что это даёт, кроме как лишнюю нагрузку на сервера магазина. ·>И представь себе — выходит очередная версия компилятора с новыми фичами оптимизации и весь мир ломится на несчастные сервера магазина для обновления _всех_ приложений под _все_ платформы.
Ну, против этого есть и здравый смысл, и защита. В гугловском магазине и, думаю, не только в нём, есть вариант "анонсировать обновление только K процентов пользователей", с дискретом для K типа 10, а, может, и меньше. А по жалобам, если что — откатить срочно назад.
Здравствуйте, netch80, Вы писали:
N>И, чем дальше отличается задача от мейнстрима вбивания инструкций в конвейеры процессора — тем менее важна вылизанность нативности. На партиционировании в quicksort слишком много сравнений, чтобы нативность что-то дала.
Даст не нативность, а меньшее количество индерекций в сортируемых массивах, инлайнинг компараторов и итераторов.
N>А дальше уже начинает играть роль алгоритмическая оптимизация — например,
Старые песни о главном — "ничего что всё тормозит, зато на алгоритмах вас заборем"
N>в Java quicksort partitioning это dual-pivot,
Это который Arrays.sort(int[])? Конечно сортировать прибитые гвоздями int'ы за average O(N * log(N)) — это повод для алгоритмической гордости, прям забороли-перебороли
N>а в GCC STL — introsort с выбором по тупой медиане и неуправляемой левосторонней рекурсией, соответственно, свалиться в плохой случай ей в разы легче.
Худший случай у introsort это O(N*log(N))
А у Arrays.sort на Java какая-то расплывчатая формулировка
This algorithm offers O(n log(n)) performance on many data sets
Здравствуйте, netch80, Вы писали:
I>>·>Правильно — _никакой манаджед_. Но у нас другой случай: возьмём sort — почему один манаджед даёт внятный перформанс, а другой — не даёт? I>>Это враньё. Сортировка это перепахивание RAM, то есть, именно то, ради чего стоит использовать нативный код. N>"Это враньё" ((c) Ikemefula). Перепахиванию RAM пофиг нативность кода, до тех пор, пока интерпретатор хоть как-то разумен — даже самый тупой JIT тут даёт достаточный результат.
Ему ой как не пофиг на лишние косвенности и скачки по памяти, которыми пестрит весь управляемый код. Собственно поэтому и извращаются на байт-буферах чтобы эти самые косвенности пересилить