Как стать автором
Обновить

Комментарии 53

Понятно что если система управления памятью написана на Г-коде, то будь память хоть на триггерах, все упрется в процессор. Значит, нужно лучше управлять памятью. Причем здесь диск — не понятно. И еще: а они отключили кешироваие? Если нет, то возможно дело просто в том, что аллокатор ОС лучше аллокатора рантайма.
Звучит логично. Взяли кусок данных, обработали, вызвали команду записи в файл. Операционная система получила данные для записи, записала их в дисковый кеш и вернула управление программе. Программа занялась вычислением следующей порции данных, контроллер диска занялся записью данных из кеша на диск. Имеем распараллеливание задач вычисления и записи данных. Если все сначала вычислить, а потом записывать, распараллеливания не происходит.
Перевод такой же плохой, как оригинальная статья.

Они сравнивают 1 миллион созданий объектов с копированием данных из двух предыдущих и 1 миллион операций передачи данных ОС. Исходный код есть глубоко в ссылках.

Идиоты.
Полная ерунда, а не исследование — надо смотреть на код. В примере «in-memory» они в начале делают многократную конкатенацию строк в цикле — на каждый шаг цикла java создаст по новому объекту строки, что и приводит к большому времени работы. И лишь потом они сбрасывают это на диск…

Прежде чем делать заявления о скорости работы платформы с памятью им следовало бы изучить базовые принципы работы java.
О чем собственно они и говорят. Разработчики, которые не знают как джава(да впрочем и любой ЯВУ) работает с памятью как раз и сталкиваются с такими проблемами!
Это как раз к вопросу «а зачем нам знать основы работы компьютера» при обучении программированию. О чем к концу статьи и сделали замечание.
Кто-нибудь скинет исследователям статью про StringBuilder?
Они сам говорят, что Java и Python совершают много работы за кулисами и тем не менее всё равно их используют. Даже ежу гуманитарию понятно, что нужно было использовать C для тестов.
Введение не соответствует сути статьи.
У вас не HDD быстрее RAM. У вас работа с HDD быстрее чем работа с RAM в некоторых случаях при использовании языков высокого уровня. А если точнее — языков с не прямым управлением памятью.
Конечно работа с оперативкой будет медленней, если на добавление каждого нового байта(или кучки байт) у вас будет realloc. А на всяких java и python у вас именно так и будет.
Если же писать на языке дающим возможность управлять памятью напрямую, то выделяется фиксированный буфер и до его заполнения пишем в него, как заполнился — сбрасываем на жесткий — будет быстрее. Я гарантирую это.
Что характерно искусственная буферизация на уровне кода работает все равно лучше чем решение из ОС. Во всяком случае когда мы проводили тесты на винде — искусственная буферизация в коде давала прирост скорости по сравнению с тупым писанием каждого байта через ОС.
Закономерно — системные вызовы не бесплатны.
А чего системного в записи на диск? Если там буферизация, то это обычный вызов dll метода, а не вызов метода драйвера или ядра.
Если бы это было так просто, использование буфера в программе давало бы минимальный выигрыш.
О чем и речь.
Так ведь от этого как раз и хотят уходить в ЯВУ. Человек ставит задачу — машина выполняет. В идеале, человеку не надо знать КАК машина выполняет задание главное чтобы быстро, но современные ЯВУ пока далеки от этого. Поэтому и возникают подобные ситуации, и новое поколение программистов «зачем нам знать принципы работы ЭВМ, мы программировать умеем» сталкивается с такой неожиданностью!
Вот именно. Пока не получается.
ИМХО попытки пока создают проблем больше чем решают.
Возможно во мне говорит любитель не управляемых языков, конечно.
Но в целом впечатление от языков с управлением памятью негативное. Запоминать нюансов работы с GC приходит больше чем правил по работе с указателями в неуправляемых языках.
Как отметил товарищ madfly все зависит от распараллеливания задач. Чтоб делать громкое заявления HDD быстрее(иногда) DDR нужно во первых отключить дисковый кэш, перевести планировщик ввода/вывода в режим «noop», использовать один процессор(с одним ядром и без поддержки физических потоков).
И, конечно, добавить в итоге результаты нагрузки на CPU.
В целом — тест не о чем.
Это если надо протестировать железо… а тут похоже тестировались именно языки программирования.
Не знаю, как в Java, а в CPython у вас будет никак не realloc. А создание нового объекта‐строки (с выделением памяти, возможно (Python имеет собственный аллокатор и может использовать ранее полученную память), с помощью системного вызова), уменьшение счётчика ссылок и, если он обнулился, немедленное удаление и освобождение памяти из‐под старого объекта (сначала в свой аллокатор, ещё не в системный free).

У Java, насколько мне известно, тоже собственный аллокатор. А с используемой авторами неизменяемой String должно быть что‐то похожее. Я сильно подозреваю, что realloc было бы быстрее, если только аллокаторы языков не забрали себе побольше памяти, на несколько таких промежуточных объектов сразу (в Java наверняка так, в CPython не уверен).
Я не имел ввиду системный realloc.
имел ввиду операцию создания нового блока памяти с копированием туда данных из предыдущего.
В языках с неизменяемыми строковыми типами (т.е. почти во всех языках со сборкой мусора) чистого realloc на таком коде не будет — это будет всегда тройка malloc+memcpy+free или эквивалентов (скорее всего, с собственным аллокатором), причём free во многих из них будет очень сильно отставать от malloc по времени из‐за того, что сборка мусора происходит далеко не сразу.

Я это к тому, что realloc по своей сути* предполагает немедленное удаление старой памяти. Этого не происходит и забывать про GC, считая что происходит эквивалент realloc в коде, нельзя: вполне можете однажды обнаружить кучу занятой памяти или внезапные заморозки (а то и то, и другое). Что‐то вроде realloc произойдёт только в CPython с его примитивным GC, основанном на счётчике ссылок.

* Если забыть про возможность просто расширить уже имеющийся блок, что в C бы происходило на таких операциях часто — с моей libc на моей системе можно прибавить до 23 байт включительно (при условии, что size mod 24 = 1), величина связана с выравниванием для выделяемых блоков:

% echo $'#include <stdlib.h>\nmain(){void *p = malloc(1); printf("%p\\n", p); p = realloc(p, 2); printf("%p\\n", p);}' | tcc -run -
0x1e20170
0x1e20170
О чем и речь.
Если в неуправляемых языка есть шанс, что просто изменится объем выделенной памяти, то на всяких java мы все время будем копировать куски памяти. Хотя могу ошибаться, возможно там все таки внутри есть алгоритмы, которые позволяют в таких ситуациях просто добавить памяти без перемещения данных.
Со StringBuilder примерно так и будет работать.
Что тут можно сказать, не используйте Яву и не пишите тупой код.
Осталось только мелочь… научиться отличать тупой код от нормального.
А она (тупость) в каждом языке своя. Тупой код для одного языка может быть нормальным для другого :-) Зависит как от семантики компилятора, так и от железа, на котором потом скомпилированный код будет выполняться. Так что подобные статейки вызывают легкое недоумение :)
А когда авторы кроме работы с процессором/памятью начинают работать еще и с диском, тут еще подключается оптимизация самого диска (NCQ, буфер), драйвер, кэширующая прослойка ОС. А вдруг диск — это SSD — там свои тараканы. Авторам статьи я бы пожелал не заниматься таким поверхностым анализом.
А если RAM-диск… и поднятая проблема становится не такой очевидной.

Так ведь если проблема вскрылась даже при поверхностном анализе…
Чем джава-язык хорош — высокая абстракция от железа, чтобы программировать на нем не надо вникать в особенности работы железа. Так должно быть! Но пример показывает обратное, что даже в джаве нужно учитывать тонкости реализации на низком уровне — вот это уже не нормально! Иначе накой все эти джавы, с#… когда можно писать код-конфетку на чистом C.
А в чем, собственно, проблем писать на С/С++ под любую платформу? Как от железа зависит код?
Писал кроссплатформенный фреймворк и единственную проблему примоминаю — это необходимость учитывать BIG_ENDIAN/LITTLE_ENDIAN. В остальном С++ код одинаково компилится под все мне доступные платформы.
Я не могу представить прикладную задачу, которая бы резко стала сложнее от того, что ее надо делать кроссплатформенной.

Всегда думал, что основная фишечка java и аналогов — это GC. Не?
Так ведь, суть то в чем… это требует более высокой квалификации. От этого стараются избавится — хотят чтобы было много легко заменимой рабочей силы, чтобы любая обезъяна могла прямо с улицы прийти и продолжить писать проект.
Так вот эти «британские учёные» и посадили обезьяну за Питон, что у них работа с жёстким диском оказалась эффективнее работы с памятью.)
чтобы программировать на нем не надо вникать в особенности работы железа

А как в них не вникать-то? Нужно хотя бы представлять, какие действия быстрые, а какие медленные.
Закон дырявых абстракций.
был написан на Java и Python

дальше не читал.
Каждой задаче свой язык. Я согласен, что для некоторых задач к сожалению применимы в данный момент C/C++. Это не означает, что остальные языки для развлечений.
Я лично не большой фанат языков подобных C или С++ потому, что их сложность и неоднозначность отвлекают от алгоритмической части. Тем не менее я трачу порядка 80% своего рабочего времени именно на написание кода на них. В свободное от работы время с удовольствием балуюсь Python или Ruby.
Простите, не хочу затевать холивар, но мимо таких заявлений не могу пройти…
На С++ действительно можно создать себе проблем.
#define TRUE FALSE
Но на С++ можно писать нормальный код, который нормально работает. Достаточно просто не канифолить себе мозг пытаясь конструкцией покороче решить проблему побольше.

Я много пишу на С++. Но вот так навскидку не могу припомнить кода, который бы вызывал проблемы.
Я мало пишу на Java, но легко вспомню пример, который меня просто убил:
GC как-то по особенному работает с Bitmap на Android, и чтобы не получить OOM — надо ручками вызывать Bitmap.recycle(). Хотя казалось бы — язык должен сам следить за работой с памятью и не должен отвлекать от написания алгоритмов…
AllexIn у каждого языка и его библиотек есть свои сильные и слабые стороны и, естественно, свои ниши применения.
Но IMHO нельзя сказать, что программа написанная на C++ автоматически работает быстрее, чем, например, на Python.
Очень многое зависит от реализации платформы и собственно алгоритма.
Естественно, GC вносит свои 5 копеек в производительность, но с другой стороны в некоторых случаях он может даже в итоге ее увеличить. К примеру immutable объекты в правильной реализации не дублируются. Это означает, что если Вы пишете многопоточную программу которая имеет дело с однородными данными(скажем frontend распределенной файловой системы) то потребление памяти может оказаться ниже нежели при написании на C++, что приводит к меньшей фрагментации последней.
И никто не говорил, что написание на C++ невозможно писать нормально =). Ровные руки и дело в шляпе.
Ну, все мы знаем как работает Эклипс.
Мне сама IDE очень нравится. Но ее стабильность и потребление памяти — известные проблемы.
Сложно представить, что Эклипс пишут криворучки.
Вы думаете Eclipse работал бы быстрее и стабильнее, если бы был написан на C++?
А что думать-то. Полно IDE написанных на С++, которые работают стабильнее при сравнимых возможностях.
Я не могу в данном случае вступить в дискуссию поскольку использую Emacs, база которого написана на C, но все расширения, которые собственно и делает его чем-то большим чем просто текстовым редактором — на Lisp. И да — работает все это отлично.
В случае Java мне кажется есть какое-то непонимание, возможно и с моей стороны в том числе. Я лично не разрабатываю на Java, но мне всегда казалось что GC не основная ее проблема(как и многих других языков bytecode которых не подвергается агрессивным оптимизациям как в случае с GCC).
Примеры? С указанием потребления памяти. И пожалуйста, чтобы это были IDE, а не текстовые редакторы с надстройками.
Eclipse(Java) и Qt Creator(Qt + C++) на слабой машине с 12 убунтой. С относительно небольшим проектом(три сотни тысяч строк кода), очень чувствуется разница.

Под виндой мне тоже не нравится производительность студии, гуи(редактор, хотя тут не уверен) которой написан на wpf, но очень удобная.
НЛО прилетело и опубликовало эту надпись здесь
А смысл от примеров? Чтобы в ответ можно было сказать «А Эклпис умеет вот это, а ваша IDE — не умеет!». Так всегда можно будет сказать, потому что идеентичных IDE не бывает и у каждой свои особенности.
Нет, проблемы неизвестные. У тысяч людей всё нормально со стабильностью и потреблением памяти.
гугл и запрос Eclipse lags не согласны с вами.
Да даже в гугл не обязательно ходить. Хабр содержит некоторое количество статей описывающих проблемы Эклипса.
BigData… Java… Python… Моя плакать…
Это означает что Вы не занимаетесь распределенными вычислениями и обработкой больших массивов данных?
Вы совершенно правы. Для меня понятия «интерпретируемый язык» и «большие объёмы данных» несовместны. Но я не утверждаю, что я прав, потому что никогда БигДатой не занимался.
Byte code, JVM, не?
* «интерпретируемый байткод» и «большие объёмы данных»
НЛО прилетело и опубликовало эту надпись здесь
Довольно тупое исследование. Поясню по русски, т.к. тут самый главный момент упущен, а перевод ужасен.
Есть много много строк. Задача — записать их последовательно в файл.
Вариант решения 1: Конкатенируем все строки в один большой буфер, а потом его записываем в файл.
Вариант решения 2: Открываем файл и по очереди записываем в него строки.
Ну ясен пень, в что в первом варианте добавляется лишняя операция — конкатенация, которую можно опустить, что и делается во втором варианте. Язык, платформа, кеширование, это всё тут не при чем. Конечно в любых обстоятельствах первый вариант будет проигрывать по производительности, тупо по тому, что выполняется больше действий.
Этот «эксперимент» доказывает одно — что написать код, который делает много операций, то он будет работать медленнее, чем код который делает меньше операций.
Вы написали правильный вариант решения 1. Они использовали другой способ.
Чего?
А если ещё учесть размер кластера раздела, то наверняка ещё быстрее можно сохранить.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории