Больше чем Java?
Закончив очередной проект на Java, я попытался разобраться в причинах накопившегося раздражения. Да я люблю Яву и все такое, но… Есть несколько «но», которые досаждают. Приходится писать довольно много шаблонного кода, с генерацией которого вполне может справиться сам компилятор, IDE, конечно, выручает, но это не решение проблемы, а скорее костыль: если что-то изменилось, нужно перегенерить и вычистить и т.д. Проверки на null! Это зубная боль, по-хорошему, нужно делать их всегда дабы не нарваться на «нежданчик» в виде NullPointerException в самый неподходящий момент. Короче говоря, появилось желание посмотреть, что еще появилось в природе и сможет ли это нечто заменить мне Java. Дальше имеет смысл описать участников данного сравнения. Сразу скажу, что не претендую на полноту анализа, к сожалению, у меня было слишком мало времени, чтобы как следует познакомиться с каждым языком.
Обязательные требования к претендентам, которые у меня были:
• Язык общего назначения
• Кроссплатформенность (хотя бы Windows/Linux)
• Стабильность
• Статическая типизация
• Автоматическая уборка памяти
• Поддержка полноценной объектно-ориентированной парадигмы
• Хорошая поддержка в IDE (Eclipse, IDEA или на худой конец NetBeans)
• Безгемморойный доступ к существующим фреймворкам/библиотекам
• Производительность на уровне Java
Помимо этого очень хотелось бы:
• Null pointer безопасность обеспечивающаяся языком на этапе компиляции
• Простые приведения типов без рудиментов из С
• Возможность разумной перегрузки операторов
• Чтобы, наконец-то, были почищены базовые типы. Ну на фига тянуть в новый язык из бородатых времен всякие float/double, short/int/long? Может это и имело смысл во времена i386 процессоров, которые могли иметь математический сопроцессор, а могли и нет. Все эти тонкости могут жить в ядре операционной системы поближе к железу и не высовываться наверх. Базовые сущности: Integer и Float вот и все, что должно быть, детали пусть рулит компилятор.
• Гармоничное сосуществование лямбд
• Общий продуманный и целостный дизайн языка
• Выразительность, поменьше ASCII арта и загадочных конструкций, на которые хочется побрызгать святой водой
• Нормальные строки, в которых символы представлены не суррогатными парами или россыпью байтов, а полноценными Unicode point-ами.
Должен отметить, что в обзор не попал целый пласт языков, которые компилируются в нативные бинари или в C. Возможно, они и замечательные, но попробовав несколько вариантов типа D, Nim, Eiffel, Rust, Go, и еще чего-то я пришел к выводу, что не буду углубляться в эти изыскания. Проверка была очень простая – HelloWord. Бинарь получившийся на выходе обычно измерялся мегабайтами. Т.е. маленькая програмулька, которая печатает в консоль тупую строчку и должна занимать от силы 3-4Кб весит мегабайты! Мелочь скажете вы. Да мелочь, я понимаю, создатели языка впихивают в бинари всю мощь и богатство своего детища, но можно же было как-то оптимизировать это!? Если требуется только печать, зачем запузыривать в бинарь все что есть на свете? Ну вынесите минимально необходимую часть в статическую библиотеку, а все остальное в динамические либы. Если не ошибаюсь, создатели D и Rust позиционируют эти языки пригодными для написания ядра операционной системы. Вы серьезно, ребята? А вот всю эту “красоту”, мегабайты вспомогательного кода языка, с кучей системных вызовов Window/Linux вы тоже предлагаете затянуть в ядро? В общем, этот класс языков не вписался в мое требование «кросплатформенность» и «стабильность» (ну и с «автоматической уборкой памяти» и «объектно-ориентированностью» не всегда все гладко, то интерфейсы забудут добавить, то вместо классов какие-то сомнительные альтернативы предлагают) т.к. они содержат очень жирную прослойку между языком и операционной системой, а качество и стабильность этого кода вызывает много вопросов. Может быть он очень хорош, я не знаю, а если нет? Все-таки JVM и Java SDK проверены годами и прекрасно трудятся на разных ОС. Поэтому все рассматриваемые далее языки в той или иной мере опираются на JVM. Теперь перейдем к списку наших участников, с небольшим описанием, а точнее с моими субъективными впечатлениями, не стоит воспринимать их слишком серьезно.
C# (MSVC2015) — вошел в обзор только потому, что мне довелось написать на нем немалое количество строк, и никаких преимуществ по сравнению с Java я в нем не обнаружил. Скорее наоборот. К тому же с кросплатформенностью тут все не слишком радужно, родная для него платформа Windows, а mono не дает полноценной замены на Linux (см. ниже). Но мне было интересно сравнить его с точки зрения производительности с остальными участниками.
Qt/C++ (5.10) — так же был добавлен исключительно для сравнения производительности.
Ceylon (1.3.3) – этот замечательный язык был создан в 2011 Гавином Кингом, автором известного фреймворка для Java Hibernate и поддерживается сейчас сообществом RedHat. Язык очень красив, продуман, и выразителен. Наверное, так бы выглядела Java если бы развивалась без гнета обратной совместимости. Язык включает в себя все мои вышеперечисленные «хотелки» и даже более того. Я действительно стал поклонником этого языка и потратил больше всего времени на его изучение, к сожалению, информации по нему не очень много, а сообщество не слишком многочисленное и активное. На мой вкус язык почти идеален, но хотелось бы упомянуть и о недостатках. Есть плагины для Eclipse/IDE, они сделаны весьма хорошо, но оптимизация не на высшем уровне, короче говоря, они безбожно тормозят. Запуск тестов (есть специальный фреймворк для тестирования) может занять 7(!) секунд, причем сами тесты выполняются мгновенно, но старт очень неторопливый.
Скорее всего, это связано со вторым недостатком – вшитую в язык систему модульности, нет, я не хочу сказать, что модульность сама по себе это недостаток, я лишь имел ввиду, что встроенные в язык конкретные вещи становятся безальтернативными и это плохо. Так вот в Цейлоне модули имеют свой формат (.car файлы), а основано это все на системе модулей JBoss. Еще создатели языка почему-то отказались от ‘protected’, что не дает возможность реализовать, например, такой шаблон проектирования как «Шаблонный метод».
Scala (2.12) – такое впечатление, что создатели языка руководствовались, в основном, принципом «а давайте сделаем все ни как у людей». Вместо привычной * сделали _, а зачем? Видимо, «чтобы никто не догадался» (с). Все знают, что массив это обычно [], так давайте сделаем () и пусть им вынесет мозг. А что же тогда будет значить []? А давайте это будут дженерики? Давайте… И так далее. Чтобы вы думали значит a < — b? Я было подумал, ну небось, клонирование, или запихнуть все из коллекции b в коллекцию a, ан нет, это обход коллекции…
А почему? Да потому, что это Scala, потому что они с Тау Кита, кровь у них фиолетовая и мозги работают по-другому, короче они иные… Взяли и вшили в язык XML… Нужно, видимо, пойти дальше и встроить прям в язык Microsoft Office, почему нет? Строго внести в стандарт языка формат xls файлов… По началу, все это вызывает раздражение (еще и дурацкие названия стандартных классов – StringOps как вам?), кто-то плюнет и скажет, а ну ее эту скалу. А адепты презрительно пожмут плечами, мол, нехай сиволапый лезть в наши микросхемы, раз не понимаешь ни хрена, мы тут элита. Ну а если серьезно, обычные язык, без откровений, к сожалению, нет защиты от null pointer, только optional. Есть скользкие места и ловушки для новичков, я не уверен, что это хорошее решение для коллективного творчества.
Kotlin (1.2) – напомнил мне гнездо сороки: тут серебряная ложечка, тут фантик от конфетки… Девизом ребят, видимо, была песня «я тебя слепила из того что было». Взять из других языков проверенные временем решения и соединить, почему нет? Создатели языка называют это прагматичным подходом. Только иногда, как мне кажется, их подводил недостаток вкуса что ли (или чувства «прекрасного», на секундочку). Глядя на такую дичь как, return@forEach (прям e-mail какой-то) хочется выругаться интеллигентно и дать зарок не пользоваться этим. Но в целом язык мне все-таки понравился, лаконичный, все, что нужно есть. Жаль только присваивание в выражениях запретили и базовые типы не почистили как в Ceylon-е (вероятно, для меньших усилий при стыковке с Явой).
Fantom (1.0.69) – это такая «вещь в себе», фантомная, вроде бы уже существует с 2005 года, а вроде как и нет его. Взял в оборот исключительно из-за байки будто бы он рвет «как Тузик грелку» по производительности Яву на ее же JVM-е, ну и вообще, интересно было взглянуть на язык который компилируется в некие самопальные fcode, которые потом могут транслироваться как на JVM так и на CLR. Что сказать про сам язык? После того как я прочитал, что дженерики «пока еще не поддерживается», но это «пока» длится с каких-то там мохнатых годов и по-видимому так и останется, мой практический интерес к этому языку угас. Если быть точным поддержка дженериков там есть, но только для встроенных коллекций, а этого для инструмента разработки промышленного уровня, на мой взгляд, недостаточно. С одной стороны вроде бы есть nullable types – “Str? str”, но компилятор не препятствует обращению к str без проверки на null. Обидно…
D (dmd 2.078.2) — был добавлен позднее, исключительно из спортивного интереса как дополнительный участник не с JVM. К сожалению писать на D не слишком комфортно из-за отсутствия IDE с «человеческим лицом». На сайте приводится целый список «IDE», некоторые даже написаны на самом D, но на поверку все это оказывается, пардон, лаж… неправдой. Все они непригодны для комфортного написания кода. Реально на чем можно хоть как-то «лабать» это плагин для Idea, но и там нет кода завешителя даже после точки. Наиболее пригодный для работы это DDT плагин для Eclipse, но его автор написал, что прекращает работу над проектом, видимо, разочаровавшись в D. Прискорбно.
У меня не было времени, чтобы детально исследовать/анализировать/тестировать каждый аспект языка отдельно, поэтому было принято решение написать на всех исследуемых языках, похожий код с тем же набором классов/логики и чтобы обязательно было задействовано:
• Интенсивный I/O
• Парсинг строк
• Вычисления с плавающей точкой с использованием математических функций: sin, cos, atan2, toRadians, sqrt
• Работа с коллекциями: ассоциативными массивами и просто массивами
• Лямбды (если есть)
Если в языке присутствовали свои библиотеки, я старался использовать их, если нет, то из Java.
Под руками оказались громадные текстовые файлы из предыдущего проекта с картографическими данными, поэтому тестовые приложения делают следующую работу. В командную строку предается путь к каталогу с файлами, участник должен получить список файлов отфильтровав их по расширению и обработать каждый. Обработка заключается в построчном чтении и парсинге строки и если это сегмент (т.е. отрезок на местности с координатами начала и конца), вычислить его длину и положить в map все сегменты которые находятся в определенном радиусе от заданной точки. Ключом в map-е служит идентификатор группы сегментов. Программа сама засекает время выполнения всей операции в миллисекундах и выдает количество найденных групп сегментов.
Самый лаконичный код получился на Kotlin, самый изящный и доступный для быстрого понимания на Ceylon.
Немного скучных цифр, объем кода в строках/килобайтах:
• Ceylon: 128/4.7
• C#: 177/6.2
• Fantom: 153/3.8
• Java: 203/6.1
• Kotlin: 117/3.9
• Qt/C++: 413/8.3
• Scala: 123/3.6
• D: 204/5
Объем получившихся бинарных файлов в килобайтах:
• Ceylon (*.class): 31.1
• C# (.exe): 8.7
• Fantom (.pod): 7.5
• Java (*.class): 9.9
• Kotlin (*.class): 20.9
• Qt/C++ (*.exe Release): 37.7
• Scala (*.class): 20.7
• D (.exe, Release): 1765
Ну а теперь самое вкусное, результаты забега… Кто прибежал первым, а кто оказался аутсайдером? Делайте ваши ставки, господа! Лично мои предсказания не оправдались, а результаты удивили. Тестирование проводилось на одной машине, но на двух платформах: Windows 7 x64 Professional и Linux Debian x64 Stretch Stable. И там и там была установлена Orcale Java 8.152. На Linux скомпилированный .exe файл C# запускался через mono из стандартного репозитория Debian. Запускалось все в одинаковых условиях на незагруженной системе. Я провел два раунда, в первом на входе был только один относительно небольшой файл 30Мб — спринт, в этом случае от запуска к запуску был некоторый разброс результатов, поэтому запускал по 20 раз каждого участника и брал средний результат. Во втором раунде условия резко ужесточились, на входе было несколько файлов общим объемом около 900Мб — марафон. В этом случае разброс был значительно меньше, видимо из-за «прогретости» JVM-а. Но для чистоты эксперимента все-таки запускал 10 раз:
Windows 7 x64 Professional
Один файл (30Мб)
• Java: 621ms, 1,00
• Kotlin: 667ms, 1,07
• Scala: 745ms, 1,20
• D: 797ms, 1,28
• C#: 1143ms, 1,84
• Ceylon(JavaLibs): 1160ms, 1,87
• Fantom: 1362ms, 2,19
• Qt/C++: 1378ms, 2,22
• Ceylon: 1479ms, 2,38
Несколько файлов (~900Мб)
• Java: 22932ms, 1,00
• Scala: 23013ms, 1,00
• Kotlin: 23300ms, 1,02
• Fantom: 32047ms, 1,40
• C#: 33349ms, 1,45
• Ceylon(JavaLibs): 38466ms, 1,68
• Qt/C++: 40444ms, 1,76
• Ceylon: тест провален, участник не смог добежать до финиша и был принудительно снят с пробега по прошествии 5 минут работы над крупным файлом 738Мб (см. комментарий ниже).
• D: Мирно почил в бозе, эпитафия: “core.exception.OutOfMemoryError@src\core\exception.d(702): Memory allocation failed”
Debian x64 Stretch Stable:
Один файл (30Мб)
• Java: 612ms, 1,00
• Kotlin: 652ms, 1,07
• Scala: 686ms, 1,12
• D: 785ms, 1,28
• Qt/C++: 1023ms, 1,67
• Ceylon(JavaLibs): 1190ms, 1,94
• Fantom: 1356ms, 2,22
• Ceylon: 1480ms, 2,42
• C#: 2119ms, 3,46
Несколько файлов (~900Мб)
• Java: 22161ms, 1,00
• Scala: 22625ms, 1,02
• Kotlin: 22865ms, 1,03
• D: 22876ms, 1,03
• Qt/C++: 31349ms, 1,41
• Ceylon(JavaLibs): 34664ms, 1,56
• Fantom: 40903ms, 1,85
• C#: 68038ms, 3,07
• Ceylon: тест провален, участник испустил дух не добежав до финала с таким эпикризом: «Exception in thread «main» java.lang.OutOfMemoryError: GC overhead limit exceeded»
К сожалению, так понравившийся мне Ceylon (песня ты моя не спетая), еле-еле приплелся где-то в конце, отставание от Java существенное. Scala гнал ноздря в ноздрю с Java. Fantom естественно не произвел никаких революций. Java лидер по скорости, а вот C# немного удивил, я думал, будет где-то наравне с Java. Совсем не ожидал, что нативный код окажется в хвосте! Можно, конечно, списать на неторопливость Qt, но все же… Не, ну можно, конечно, переписать на std либах или вообще на чистый C с ассемблерным вставками, но это уже будет совсем другой код. Была надежда, что молодой да ранний Kotlin покажет близкую с Java производительность, но отставание все же есть, значительно меньше, чем Ceylon, но больше чем Scala. Причем как-то непонятно где в Kotlin может проседать перформанс, ведь у него нет своего ввода/вывода, математической библиотеки и коллекций, все это используется из Java. Вот, например, Ceylon подвели самодельные коллекции, как выяснилось, когда я стал разбираться в причинах его провала на большом объеме входных данных. Они оказались слишком прожорливы к памяти, и съели 8Гб оперативки даже не заметив, поэтому тест и «подвис», например, при запуске на машине с 24Гб памяти, тест на Ceylon проходит нормально, но, конечно, абсолютные цифры сравнивать уже нельзя, это другое железо. Мне все же удалось заставить Ceylon работать, когда я заменил коллекции из его стандартной библиотеки на коллекции из Java (HashMap и ArrayList) и тест был пройден. Так же добавил результат для Ceylon когда используются Java библиотеки для I/O и коллекция, результаты немного лучше, но не спасают ситуацию.
Кстати, попутно можно отметить, что на одном и том же железе Debian обеспечивает чуть лучшую производительность (исходные данные я подкладывал ему на ext4 раздел, а не брал их с NTFS).
Как я уже говорил, из всех участников мне больше всего понравился Ceylon, на нем мне действительно захотелось покодить. Но, похоже, что он еще не созрел для промышленного использования, создателям нужно всерьез озаботиться профилированием и подчистить узкие места, тем не менее, я буду следить за его судьбой. Из оставшихся вариантов я бы выбирал между Scala и Kotlin, они, кстати, синтаксически весьма схожи, тот же а-ля паскальный стиль объявления функций и переменных. Scala лучше оптимизирован по скорости и более стабилен, но зато в Kotlin есть «умное приведение» и null-безопасность. Я, пожалуй, пока остановлюсь на Kotlin и буду изучать его детальнее, возможно, следующий внутренний проект мы напишем на нем.
P.S. Да, да, я предвидел «код в студию» J
Вот исходники: drive.google.com/open?id=1N3sEsw4MZ33GI-PPQOw_vocahGdjg9bq
Вот тулза mp2dcf, которая конвертирует карты в «польском» формате в DCF: drive.google.com/open?id=12SlixUmpnrKH5Eh8k69m_T1tmWCVy6Ko
Карты можно скачать например тут: navitel.osm.rambler.ru
Я успел попробовать на Италии: navitel.osm.rambler.ru/?country=Italy
UPD
Обновлены цифры тестов на производительность.
Благодаря замечаниям в обсуждении код был улучшен/исправлен:
asdf87 — в C# добавлено использование BufferedStream (не оказывает заметного влияния на результат);
stack_trace — поправлен код Qt/C++, добавление в map (не оказывает заметного влияния на результат);
AlexPublic — важное замечание в Java имплементации, длина сегмента, в отличии от других языков, вычислялась по требованию, а не при создании объекта.
Еще в Scala, Kotlin и Ceylon (JavaLibs) была добавлена проверка IOException как в Java.
В Kotlin вместо Java API для чтения строк теперь используется функция-расширение из стандартной библиотеки: .useLines.
Так же поменялась методика получения результатов: был написан скрипт который автоматически запускает всех участников «забега» несколько раз и вычисляет среднее время работы и контролирует чтобы количество найденных сегментов совпадало у всех. Для теста на небольших файлах (спринт) каждый участник запускается 20 раз, на больших файлах (марафон) 10 раз. Для всех языков с JVM выставлено -Xmx2g.
UPD
1) Ради спортивного интереса добавил в «забег» D. Участник показал неплохой (но не блестящий) результат, но, к сожалению, в марафоне под Windows скончался от недостатка памяти (это при 8-то гигах оперативы). При том, что на этом же железе, но под Linux смог отработать нормально. Это, в общем-то, подтверждает мои сомнения насчет кросплатформенности и стабильности рантайма языка.
2) На днях вышло обновление для Kotlin 1.2.30-release-78, я пересобрал котлиновского «участника» и прогонял, соответственно, на новом релизе. И произошло чудо — на короткой дистанции Kotlin смог вырваться на второе место! И это без каких-либо оптимизаций в коде. Выражаю респект команде разработчиков Kotlin, молодцы ребята — так держать! Верю что Kotlin может показать равную с Java производительность сохранив все свои «плюшки».
Сколько «весит» Java?
Вы используете Internet Explorer устаревшей и не поддерживаемой более версии. Чтобы не было проблем с отображением сайтов или форумов обновите его до версии 7.0 или более новой. Ещё лучше — поставьте браузер Opera или Mozilla Firefox.
Обсудить и задать вопросы можно в этой теме.
Centuriones #30.03.2005 21:55
Centuriones
опытный
Может кто-нибудь подсказать — сколько весят следующие версии Java (в Мб):
- NetBeans IDE + JDK 5.0 Update 2
- JDK 5.0 Update 2 includes the JVM technology
- JRE 5.0 Update 2 includes the JVM technology
По старой традиции, разработчики забывают указывать «километраж» в загрузочных разделах сайтов.
Заодно: что лучше использовать в качестве среды разработки — NetBeans IDE или eclipse?
Раньше были времена,
А теперь мгновения.
Раньше поднимался дух,
А теперь давление.

Balancer
администратор
Centuriones> По старой традиции, разработчики забывают указывать «километраж» в загрузочных разделах сайтов.
Хм. А набрать wget -S —spider «http://. » не судьба?
Кроме того, всё там прекрасно указано
J2SE and NetBeans IDE Bundle NB 4.0 / J2SE 5.0 Update 2 FCS Click below to download
Linux Platform
(jdk-1_5_0_02-nb-4_0-ml-linux.bin, 103.28 MB)
Solaris SPARC Platform
(jdk-1_5_0_02-nb-4_0-ml-solsparc.bin, 110.45 MB)
Solaris x86 Platform
(jdk-1_5_0_02-nb-4_0-ml-solx86.bin, 102.83 MB)
Windows Platform
(jdk-1_5_0_02-nb-4_0-ml-win.exe, 102.00 MB)
J2SE(TM) Development Kit 5.0 Update 2 Click below to download
Windows Platform
Windows Offline Installation, Multi-language (jdk-1_5_0_02-windows-i586-p.exe, 51.10 MB)
Windows Online Installation, Multi-language (jdk-1_5_0_02-windows-i586-p-iftw.exe, 221.27 KB)
Linux Platform
Linux RPM in self-extracting file (jdk-1_5_0_02-linux-i586-rpm.bin, 42.55 MB)
Linux self-extracting file (jdk-1_5_0_02-linux-i586.bin, 44.02 MB)
Solaris SPARC Platform
Solaris SPARC 32-bit self-extracting file (jdk-1_5_0_02-solaris-sparc.sh, 47.81 MB)
Solaris SPARC 32-bit packages — tar.Z (jdk-1_5_0_02-solaris-sparc.tar.Z, 83.66 MB)
Solaris SPARC 64-bit self-extracting file (jdk-1_5_0_02-solaris-sparcv9.sh, 9.55 MB)
Solaris SPARC 64-bit packages — tar.Z (jdk-1_5_0_02-solaris-sparcv9.tar.Z, 11.90 MB)
Solaris x86 Platform
Solaris x86 self-extracting file (jdk-1_5_0_02-solaris-i586.sh, 42.53 MB)
Solaris x86 packages — tar.Z (jdk-1_5_0_02-solaris-i586.tar.Z, 78.02 MB)
Linux AMD64 Platform
Linux AMD64 RPM in self-extracting file (jdk-1_5_0_02-linux-amd64-rpm.bin, 39.19 MB)
Linux AMD64 self-extracting file (jdk-1_5_0_02-linux-amd64.bin, 40.17 MB)
Solaris AMD64 Platform
Solaris AMD64 self-extracting file (jdk-1_5_0_02-solaris-amd64.sh, 5.79 MB)
Solaris AMD64 packages — tar.Z (jdk-1_5_0_02-solaris-amd64.tar.Z, 8.07 MB)
J2SE(TM) Runtime Environment 5.0 Update 2 Click below to download
Windows Platform
Windows Offline Installation, Multi-language (jre-1_5_0_02-windows-i586-p.exe, 15.25 MB)
Windows Online Installation, Multi-language (jre-1_5_0_02-windows-i586-p-iftw.exe, 221.27 KB)
Linux Platform
Linux RPM in self-extracting file (jre-1_5_0_02-linux-i586-rpm.bin, 15.27 MB)
Linux self-extracting file (jre-1_5_0_02-linux-i586.bin, 15.78 MB)
Solaris SPARC Platform
Solaris SPARC 32-bit self-extracting file (jre-1_5_0_02-solaris-sparc.sh, 19.45 MB)
Solaris SPARC 64-bit self-extracting file (jre-1_5_0_02-solaris-sparcv9.sh, 8.33 MB)
Solaris x86 Platform
Solaris x86 self-extracting file (jre-1_5_0_02-solaris-i586.sh, 14.44 MB)
Solaris AMD64 Platform
Solaris AMD64 self-extracting file (jre-1_5_0_02-solaris-amd64.sh, 4.72 MB)
Linux AMD64 Platform
Linux AMD64 RPM in self-extracting file (jre-1_5_0_02-linux-amd64-rpm.bin, 14.91 MB)
Linux AMD64 self-extracting file (jre-1_5_0_02-linux-amd64.bin, 15.41 MB)
Centuriones #30.03.2005 22:45

Centuriones
опытный
Ром, спасибо большое. Просто, наверно час бродил по java.sun.com и толком ничего не нашел. А оказалось, что надо просто нажать download . Кстати, а wget -S —spider «http://. » — это что такое?
Раньше были времена,
А теперь мгновения.
Раньше поднимался дух,
А теперь давление.
Это сообщение редактировалось 31.03.2005 в 00:49

Mishka
модератор
Я за Борланд. Но Эклипс тоже ничего, хотя и значительно проще.

Lerm
втянувшийся
IDE нужно выбирать исходя, в первую очередь, из задач (т.е. если например писать под WebSphere, то лучше использовать WSAD). Если абстрактно: из бесплатных — Eclipse, из коммерческих — IDEA (впрочем, объективные критерии для выбора IDE подобрать сложно — каждый использует то, что ему нравится. Тема выбора IDE (и их сравнения) — вечный флейм на программистских форумах). B)
You live and learn. Or you don’t live long.

Balancer
администратор
Я для работы с проектом на 450 файлов и 2.5Мб исходников использую исключительно FAR Manager с Colorer’ом Получается быстрее и удобнее, чем в Eclipce.
Но это, возможно, индивидуальное
Про wget — утилита это консольная для скачивания. Порт с *nix’ов. Очень копактная и мощная. Годится от простого выкачивания файлов (чем я очень часто занимаюсь) до выкачиывания целых сайтов, в т.ч. с конверсией ссылок и т.п., организации всяких хитрых запросов и т.п.
Lerm #31.03.2005 12:35 @Balancer#31.03.2005 10:55

Lerm
втянувшийся
[quote|Balancer, 30.03.2005 22:55:20:]
Я для работы с проектом на 450 файлов и 2.5Мб исходников использую исключительно FAR Manager с Colorer’ом Получается быстрее и удобнее, чем в Eclipce.
Но это, возможно, индивидуальное
Да, Far в сочетании с Colorer довольно удобен (сам использовал так), особенно при наличии хороших скриптов сборки (опять таки, ANT не забываем. ).
Однако, хорошее IDE позволяет экономить время за счет моментального обнаружения синтаксических ошибок, предоставление опять-таки моментальных контекстных подсказок и справки, быстрых переходов к нужным классам (и файлам) по их именам, автоматической поддержки требуемого стиля форматирования, средств рефакторинга (например, безопасное переименование класса — автоматическое изменение всех мест, в которых используется класс, или, скажем, смена сигнатуры метода и т.д.), средства генерации наиболее часто используемых синтаксических конструкций (например, LiveTemplates в IDEA — набираем psvm, нажимаем Tab — получаем готовое определение метода main, аналогичные шаблоны для итераторов, ввода-вывода и т.д.) и многое другое. В принципе, все современные хорошие IDE (вроде Eclipse, IDEA, NetBeans, JBuilder, JDeveloper и их производных) включают в себя эти средства (кто-то более полно, кто-то мененее).
Главный недостаток большинства продвинутых IDE для Java — некоторая «задумчивость» при малом объеме доступной памяти. Да, все эти среды память кушать любят.
You live and learn. Or you don’t live long.

Balancer
администратор
Не только при малых У меня на 3ГГц и 1Гб, при полноценной работе в среде всё нормально, но вот после разовой сборки и попытке загрузить участок с ошибкой, задержки достигают десятка секунд. В FAR’е я это же делаю раза в три быстрее. Собственно, почему его и предпочитаю
Все сервисные возможности (типа упомянутого переименования класса) очень полезны (или, например, работа с CVS и т.п.), но используются нечасто. Для них — не грех воспользоваться и IDE. А вот цикл правка/компиляция/запуск/исправление ошибок у меня быстрее выходит в FAR’е
Ну и синтакисечкая подсветка Colorer’а для Java мне больше по душе, чем в Eclipce. Плюс вертикальные блоки, интеграция с файлменеджером и т.п.
Сколько весит java
Давайте рассмотрим на практике, создав класс с примерами объектов, которые будут использовать наш класс:
public class InstrumentationExample < public static void printObjectSize(Object object) < System.out.println("Object type: " + object.getClass() + ", size: " + InstrumentationAgent.getObjectSize(object) + " bytes"); >public static void main(String[] arguments) < String emptyString = ""; String string = "Estimating Object Size Using Instrumentation"; String[] stringArray = < emptyString, string, "com.baeldung" >; String[] anotherStringArray = new String[100]; List stringList = new ArrayList<>(); StringBuilder stringBuilder = new StringBuilder(100); int maxIntPrimitive = Integer.MAX_VALUE; int minIntPrimitive = Integer.MIN_VALUE; Integer maxInteger = Integer.MAX_VALUE; Integer minInteger = Integer.MIN_VALUE; long zeroLong = 0L; double zeroDouble = 0.0; boolean falseBoolean = false; Object object = new Object(); class EmptyClass < >EmptyClass emptyClass = new EmptyClass(); class StringClass < public String s; >StringClass stringClass = new StringClass(); printObjectSize(emptyString); printObjectSize(string); printObjectSize(stringArray); printObjectSize(anotherStringArray); printObjectSize(stringList); printObjectSize(stringBuilder); printObjectSize(maxIntPrimitive); printObjectSize(minIntPrimitive); printObjectSize(maxInteger); printObjectSize(minInteger); printObjectSize(zeroLong); printObjectSize(zeroDouble); printObjectSize(falseBoolean); printObjectSize(Day.TUESDAY); printObjectSize(object); printObjectSize(emptyClass); printObjectSize(stringClass); > public enum Day < MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY >>
Чтобы это сработало, нам необходимо включить параметр -javaagent с путем к нашему JAR-файлу при запуске приложения:
VM Options: -javaagent:"path_to_agent_directory\InstrumentationAgent.jar"
Результат работы нашего класса покажет нам приблизительные размеры объектов:
Сколько весит java
Одной из основных особенностей Java является то, что данный язык является строго типизированным. А это значит, что каждая переменная и константа представляет определенный тип и данный тип строго определен. Тип данных определяет диапазон значений, которые может хранить переменная или константа.
Итак, рассмотрим систему встроенных базовых типов данных, которая используется для создания переменных в Java. А она представлена следующими типами.
-
boolean : хранит значение true или false
boolean isActive = false; boolean isAlive = true;
byte a = 3; byte b = 8;
short a = 3; short b = 8;
int a = 4; int b = 9;
long a = 5; long b = 10;
double x = 8.5; double y = 2.7;
float x = 8.5F; float y = 2.7F;
При этом переменная может принимать только те значения, которые соответствуют ее типу. Если переменная представляет целочисленный тип, то она не может хранить дробные числа.
Целые числа
Все целочисленные литералы, например, числа 10, 4, -5, воспринимаются как значения типа int , однако мы можем присваивать целочисленные литералы другим целочисленным типам: byte , long , short . В этом случае Java автоматически осуществляет соответствующие преобразования:
byte a = 1; short b = 2; long c = 2121;
Однако если мы захотим присвоить переменной типа long очень большое число, которое выходит за пределы допустимых значений для типа int, то мы столкнемся с ошибкой во время компиляции:
long num = 2147483649;
Здесь число 2147483649 является допустимым для типа long, но выходит за предельные значения для типа int. И так как все целочисленные значения по умолчанию расцениваются как значения типа int, то компилятор укажет нам на ошибку. Чтобы решить проблему, надо добавить к числу суффикс l или L , который указывает, что число представляет тип long:
long num = 2147483649L;
Как правило, значения для целочисленных переменных задаются в десятичной системе счисления, однако мы можем применять и другие системы счисления. Например:
int num111 = 0x6F; // 16-теричная система, число 111 int num8 = 010; // 8-ричная система, число 8 int num13 = 0b1101; // 2-ичная система, число 13
Для задания шестнадцатеричного значения после символов 0x указывается число в шестнадцатеричном формате. Таким же образом восьмеричное значение указывается после символа 0 , а двоичное значение — после символов 0b .
Также целые числа поддерживают разделение разрядов числа с помощью знака подчеркивания:
int x = 123_456; int y = 234_567__789; System.out.println(x); // 123456 System.out.println(y); // 234567789
Числа с плавающей точкой
При присвоении переменной типа float дробного литерала с плавающей точкой, например, 3.1, 4.5 и т.д., Java автоматически рассматривает этот литерал как значение типа double . И чтобы указать, что данное значение должно рассматриваться как float , нам надо использовать суффикс f:
float fl = 30.6f; double db = 30.6;
И хотя в данном случае обе переменных имеют практически одно значения, но эти значения будут по-разному рассматриваться и будут занимать разное место в памяти.
Символы и строки
В качестве значения переменная символьного типа получает одиночный символ, заключенный в одинарные кавычки: char ch=’e’; . Кроме того, переменной символьного типа также можно присвоить целочисленное значение от 0 до 65535 . В этом случае переменная опять же будет хранить символ, а целочисленное значение будет указывать на номер символа в таблице символов Unicode (UTF-16). Например:
char ch=102; // символ 'f' System.out.println(ch);
Еще одной формой задания символьных переменных является шестнадцатеричная форма: переменная получает значение в шестнадцатеричной форме, которое следует после символов «\u». Например, char ch=’\u0066′; опять же будет хранить символ ‘f’.
Символьные переменные не стоит путать со строковыми, ‘a’ не идентично «a». Строковые переменные представляют объект String , который в отличие от char или int не является примитивным типом в Java:
String hello = "Hello. "; System.out.println(hello);
Кроме собственно символов, которые представляют буквы, цифры, знаки препинания, прочие символы, есть специальные наборы символов, которые называют управляющими последовательностями. Например, самая популярная последовательность — «\n». Она выполняет перенос на следующую строку. Например:
String text = "Hello \nworld"; System.out.println(text);
Результат выполнения данного кода:
Hello world
В данном случае последовательность \n будет сигналом, что необходимо сделать перевод на следующую строку.
Начиная с версии 15 Java поддерживает тестовые блоки (text blocks) — многострочный текст, облеченный в тройные кавычки. Рассмотрим, в чем их практическая польза. Например, выведем большой многострочный текст:
String text = "Вот мысль, которой весь я предан,\n"+ "Итог всего, что ум скопил.\n"+ "Лишь тот, кем бой за жизнь изведан,\n"+ "Жизнь и свободу заслужил."; System.out.println(text);
С помощью операции + мы можем присоединить к одному тексту другой, причем продолжение текста может располагаться на следующей строке. Чтобы при выводе текста происходил перенос на следующую строку, применяется последовательность \n.
Результат выполнения данного кода:
Вот мысль, которой весь я предан, Итог всего, что ум скопил. Лишь тот, кем бой за жизнь изведан, Жизнь и свободу заслужил.
Текстовые блоки, которые появились в JDK15, позволяют упростить написание многострочного текста:
String text = """ Вот мысль, которой весь я предан, Итог всего, что ум скопил. Лишь тот, кем бой за жизнь изведан, Жизнь и свободу заслужил. """; System.out.println(text);
Весь текстовый блок оборачивается в тройные кавычки, при этом не надо использовать соединение строк или последовательность \n для их переноса. Результат выполнения программы будет тем же, что и в примере выше.
