Я программировал в течение нескольких лет, и я начал на Java, и в свое время я нашел много разных источников, утверждающих, что Java так или иначе является низшим языком. Я хорошо знаю, что у каждого языка есть свои сильные и слабые стороны, но многие вещи, которые я читал о Java, кажутся устаревшими.
Наиболее часто упоминаемая причина того, что Java уступает, заключается в том, что она намного медленнее, чем другие нативно скомпилированные языки, например, C ++. Многие критикуют игрового дизайнера Нотча (который разработал Minecraft) за использование Java из-за его явного недостатка в отделе производительности. Я знаю, что в те времена Java была намного медленнее, но с тех пор было много улучшений, особенно компиляция JIT.
Я хотел бы получить некоторые объективные мнения о Java как о языке сегодня. Итак, мой вопрос состоит из 4 частей.
Представление.
а. Как скорость Java сегодня сравнивается с C ++?
б. Возможно ли создать современное название AAA с использованием Java?
с. В каких областях конкретно Java медленнее, чем C ++, если вообще? (то есть сокращение чисел, графика или просто все вокруг)
Считается ли сейчас Java компилируемым или интерпретируемым языком?
Какие основные недостатки Java были устранены с первых дней?
Каковы некоторые основные недостатки Java, которые еще предстоит устранить?
Редактировать:
Просто для пояснения, я не делаю эту Java против C ++, очевидно, в среднем C ++ будет немного быстрее, чем Java. Мне просто нужно что-то, с чем можно сравнить Java с точки зрения зрелости как языка на данный момент. Поскольку c ++ существует всегда, я подумал, что буду хорошим примером для сравнения.
источник
Ответы:
Сложно измерить. Стоит отметить, что основная часть скорости реализации, это распределитель памяти, очень разные алгоритмы в Java и C ++. Недетерминированный характер сборщика делает чрезвычайно трудным получение значимых данных о производительности по сравнению с детерминированным управлением памятью в C ++, потому что вы никогда не можете быть уверены, в каком состоянии находится сборщик. Это означает, что очень сложно написать тест это могло бы значимо сравнить их. Некоторые шаблоны распределения памяти работают намного быстрее с GC, некоторые работают намного быстрее с собственным распределителем.
Однако я бы сказал, что Java GC должен работать быстро в любой ситуации. Однако нативный распределитель можно заменить на более подходящий. Недавно я задал вопрос на SO о том, почему C #
Dictionary
может работать (0,45 мс на моей машине) по сравнению с аналогичнымstd::unordered_map
который выполнен на (10 мс на моей машине). Однако, просто заменив распределитель и хэш-код на более подходящие, я сократил это время выполнения до 0,34 мс на моей машине - тридцатая часть первоначального времени выполнения. Вы никогда не могли бы надеяться выполнить такую пользовательскую оптимизацию с Java. Отличным примером того, где это может иметь реальное значение, является многопоточность. Собственные библиотеки потоков, такие как TBB, предоставляют распределители кэширования потоков, которые значительно быстрее традиционных распределителей при работе со многими распределениями во многих потоках.Теперь многие люди будут говорить об улучшениях JIT и о том, как JIT имеет больше информации. Конечно, это правда. Но это все еще даже близко не близко к тому, что компилятор C ++ может тянуть - потому что компилятор имеет сравнительно бесконечное время и пространство для запуска с точки зрения времени выполнения конечной программы. Каждый цикл и каждый байт, которые JIT тратит на размышления о том, как лучше всего оптимизировать вашу программу, - это цикл, который ваша программа не тратит на выполнение и не может использовать для собственных нужд памяти.
Кроме того, всегда будут времена, когда оптимизация компилятора и JIT не может доказать определенную оптимизацию, особенно в случае таких вещей, как escape-анализ. В C ++, так как значение в любом случае находится в стеке , компилятору не нужно его выполнять. Кроме того, существуют простые вещи, такие как непрерывная память. Если вы выделяете массив в C ++, то вы выделяете один непрерывный массив. Если вы выделяете массив в Java, то он вообще не является смежным, потому что массив заполнен только указателями, которые могут указывать куда угодно. Это не только издержки памяти и времени для двойных косвенных указаний, но и накладные расходы кэша. В таких случаях семантика языка Java просто обязывает его работать медленнее, чем эквивалентный код C ++.
В конечном счете, мой личный опыт показывает, что Java в среднем может быть примерно вдвое медленнее, чем C ++. Тем не менее, на самом деле нет никакого способа сделать резервную копию каких-либо заявлений о производительности без чрезвычайно всеобъемлющего набора тестов из-за принципиально различных задействованных алгоритмов.
Я предполагаю, что вы имеете в виду «игру», здесь и не случайно. Во-первых, вам придется написать все с нуля, поскольку почти все существующие библиотеки и инфраструктура предназначены для C ++. Хотя это и не делает невозможным само по себе, оно, безусловно, может внести весомый вклад в невозможное. Во-вторых, даже движки C ++ вряд ли могут вписаться в крошечные ограничения памяти существующих консолей - если JVM даже существуют для этих консолей - и геймеры ПК ожидают немного больше для своей памяти. Создание эффективных AAA-игр достаточно сложно в C ++, я не понимаю, как этого можно достичь в Java. Никто никогда не писал игру ААА со значительным временем, проведенным на некомпилированном языке. Более того, это было бы чрезвычайно подвержено ошибкам. Детерминированное уничтожение необходимо при работе, например, с ресурсами GPU, а в Java вы
Я бы определенно пошел на все вокруг. Природа принудительных ссылок для всех объектов Java означает, что в Java гораздо больше косвенных ссылок и ссылок, чем в C ++ - пример, который я привел ранее для массивов, но также, например, применим ко всем объектам-членам. Когда компилятор C ++ может искать переменную-член в постоянное время, среда выполнения Java должна следовать за другим указателем. Чем больше обращений вы делаете, тем медленнее это будет, и JIT ничего не сможет с этим поделать.
В то время как C ++ может освободить и повторно использовать часть памяти практически мгновенно, в Java вам придется ждать коллекции, и я надеюсь, что эта часть не вышла из кэша, а по своей природе требуется больше памяти, что означает снижение производительности кэша и подкачки. Затем посмотрите на семантику таких вещей, как бокс и распаковка. В Java, если вы хотите ссылаться на int, вы должны динамически размещать его. Это неотъемлемая трата по сравнению с семантикой C ++.
Тогда у вас есть проблема дженериков. В Java вы можете работать только с общими объектами через наследование во время выполнения. В C ++ шаблоны имеют практически нулевые накладные расходы - что Java не может сопоставить. Это означает, что весь универсальный код в Java по своей природе медленнее, чем универсальный эквивалент в C ++.
И тогда вы приходите к неопределенному поведению. Все ненавидят, когда их программа показывает UB, и все хотят, чтобы ее не было. Тем не менее, UB в основном обеспечивает оптимизацию, которая никогда не может существовать в Java. Посмотрите на этот пост с описанием оптимизации на основе UB. Отсутствие определения поведения означает, что реализации могут выполнять больше оптимизаций и сокращать код, необходимый для проверки условий, которые не определены в C ++, но определены в Java.
По сути, семантика Java диктует, что это более медленный язык, чем C ++.
Это не вписывается ни в одну из этих групп. Я бы сказал, что управляемый - это отдельная категория, хотя я бы сказал, что это определенно больше похоже на интерпретируемый язык, чем на скомпилированный. Что еще более важно, есть только две основные управляемые системы, JVM и CLR, и когда вы говорите «управляемые», это достаточно явно.
Автоматический бокс и распаковка - единственное, что я знаю. Дженерики решают некоторые проблемы, но далеко не многие.
Их дженерики очень и очень слабые. Обобщения C # значительно сильнее - хотя, конечно, и не совсем шаблоны. Детерминированное разрушение является еще одним серьезным недостатком Любая форма лямбда / замыкания также является серьезной проблемой - вы можете забыть о функциональном API в Java. И, конечно же, всегда есть проблема производительности для тех областей, которые в них нуждаются.
источник
Начну с того, что практически никто не может дать по-настоящему нейтральное мнение о языках программирования. Если вы достаточно хорошо знаете два языка, чтобы вообще что-то комментировать, почти неизбежно, что вы предпочтете один из них другому. В качестве справедливого предупреждения я предпочитаю C ++, а не Java, что, несомненно, влияет на мои комментарии в какой-то степени.
1a. Скорость: скорость, которую вы получаете от C ++ или Java, как правило, будет меньше зависеть от языка или его реализации, чем от умения программиста (ов), использующего его. В конечном счете, C ++, вероятно, может выиграть в скорости чаще, чем нет, но различия в коде, который вы пишете, действительно важны.
1б. Да, возможно. В то же время C ++ уже хорошо зарекомендовал себя, и я сомневаюсь, что большинство игровых студий видят достаточно преимуществ, чтобы потрудиться на переходе на Java.
1c. Тщательный ответ на этот вопрос, вероятно, может заполнить большой объем. C ++, как правило, будет лучше с более ограниченными ресурсами. Java получает больше пользы от (например) наличия большого количества «запасной» памяти.
2. Медленное выполнение и медленная сборка мусора, вероятно, будут двумя наиболее очевидными. Ранняя библиотека окон (AWT) была довольно неуклюжей - Swing стал серьезным улучшением.
3. Многословие. Отсутствие перегрузки оператора. Использование сборки мусора. Отсутствие множественного наследования. Обобщения Java чрезвычайно ограничены по сравнению с шаблонами C ++.
Я должен добавить, что некоторые (все?) Из этих недостатков (особенно использование сборки мусора, но также и другие) рассматриваются многими как преимущества Java. Единственным возможным исключением будет его многословие. Ситуация с многословностью постепенно улучшается, но вы, конечно же, не часто встречаете соревнования по гольфу с выигрышным кодом на Java, и в обычном коде он также имеет тенденцию использовать довольно много кода. Я подозреваю, что есть, по крайней мере, несколько человек, которые считают его более читабельным и понятным, поэтому, вероятно, это можно рассматривать и как преимущество.
источник
источник
Во-первых, в некотором контексте мой C ++ очень ржавый, поэтому большая часть моего опыта работы с Java связана с моим более недавним опытом работы с C #, который в любом случае гораздо больше сравнивает яблоки с яблоками.
1. Скорость
Я думаю, что на этот вопрос лучше всего ответить вопрос SO. Почему Java имеет репутацию медленной? но я также думаю, что весь этот вопрос окрашен в блоге Джеффа Этвуда « Горилла против Акулы» . Спасибо Петеру и Кристоферу.
Это зависит от приоритетов разработчиков и навыков разработчиков. Кроме того, это не та или иная ситуация, для разных частей заголовка могут потребоваться разные вещи языка, на котором они реализованы, что приводит к гетерогенной языковой среде.
Я видел несколько игр, в которых недавно упоминалось, что они загружают среду Python во время загрузки, и я подозреваю, что лошади для курсов - это сильная мотивация, если вы хотите вовремя выпустить свой титул к праздничному сезону (например) ,
Вы можете писать плохо работающий код на любом языке, но некоторые языки облегчают принятие правильных решений, в то время как другие с большей вероятностью позволят себе поднять свою собственную петарду . Java относится к первой категории, C ++ определенно относится ко второй.
Как говорится, с большой силой приходит большая ответственность (не говоря уже о способности полностью испортить кучу * 8 ').
2. Считается ли сейчас Java компилируемым или интерпретируемым языком?
Я не могу сказать, что большинство людей считают, но многие знают разницу между скомпилированным и интерпретируемым языками и не жили в пещере в течение последних 20 лет, также знали бы, что JIT ( Just-in Компилятор -Time ) является важной частью экосистемы Java, поэтому, вероятно, в наши дни его с большей вероятностью можно будет считать скомпилированным.
3. Какие основные недостатки Java были устранены с первых дней?
Я довольно недавно перешел на Java, поэтому у меня мало контекста относительно того, как он развивался. Но интересно отметить, что существуют такие книги, как Java: «Хорошие части», которые стремятся направить людей в сторону тех частей языка, которые следует отдавать предпочтение в наши дни, и увести людей от областей, которые находятся или должны быть осуждается.
4. Какие основные недостатки Java еще предстоит устранить?
На мой взгляд, одной из проблем Java было медленное внедрение новых функций.
Придя в Java из C # и просмотрев страницу сравнения в Википедии, я выделяюсь следующими вещами:
Вещи, которые я скучаю по Java, по сравнению с C #
Затворы / лямбды . Я был очень разочарован, когда услышал, что поддержка Java снова отодвигается .Наконец, у нас есть Closures / lambdas в Java 8, но время, которое потребовалось, подтверждает мое утверждение о медленном принятии.var
) может показаться синтаксическим сахаром, но когда у вас есть сложные универсальные типы, он может сделать код намного понятнее, удалив много бесполезного дублирования.struct
над полным классом.Вещи, которые я не скучаю по Java, по сравнению с C #
unsafe
коду. Вы должны быть настолько осторожны с этим, что я редко находил, что это стоит дополнительных усилий.Таким образом, даже при сравнении яблок с яблоками считается, что Java отстала.
Две другие большие проблемы, с которыми я сталкиваюсь в Java, это вопиющая задержка запуска и тот факт, что (для некоторых JVM) вам приходится управлять своей кучей и даже кучей постоянного поколения . С C # приложения всегда запускались сразу, и мне никогда не приходилось даже думать о куче, так как она была выделена из пула системной памяти, а не из предварительно выделенного пула, назначенного виртуальной машине.
источник
Я могу указать вам источник, который может помочь ответить на первую часть вашего вопроса для вас. Языки программирования отрываются http://shootout.alioth.debian.org/u64q/which-programming-languages-are-fastest.php - довольно хороший источник, чтобы увидеть, как быстрые языки сравниваются друг с другом. Их можно даже отфильтровать по разным категориям, чтобы увидеть, в каких областях языки работают лучше, чем в других. Java работает намного быстрее, чем несколько лет назад.
источник
1) Строго говоря, о UX, который я получаю с Java, он кажется медленным. Я не могу сказать вам, почему на самом деле. Я еще не сталкивался с настольным приложением на основе Java, которое не кажется медленным и имеет более быструю альтернативу, не связанную с Java. Тем не менее, Java может быть очень быстрой с чистой скоростью вычислений, а Интернет полон тестов, чтобы доказать это. Однако время загрузки Java-приложений и быстродействия их графических интерфейсов еще не улучшило IMHO. Может быть, вы могли бы сделать это;)
В конце концов, скорость не так важна. Мало того, что аппаратное обеспечение становится все быстрее и быстрее, это еще и то, что большинство людей все равно удивительно мало для него заботятся, пока программное обеспечение делает то, что оно должно делать, и соотношение времени, потраченного на взаимодействие, и времени, потраченного на ожидание, является разумным.
2) Это различие стало настолько размытым в последнее время, что в этом нет особой ценности.
3 + 4) На самом деле в Java произошли некоторые изменения. Некоторые люди уже утверждают, что эти изменения опровергли чисто упрощенную философию Java, привлекая инопланетные возможности. Трудно объективно сказать, что такое недостаток и в чем сила. Для меня Java излишне многословен, ограничен и плох по функциям, в то время как другие люди считают эти черты приятной однозначностью, безопасностью и ясностью.
Так что, хотя именно эти вещи и заставляют меня не использовать Java, я не думаю, что просто добавлять то, что мне не хватает в Java, - хорошая идея. Есть много языков, которые мне нравятся работать на JVM, и сгибание Java, чтобы быть ближе к ним, просто противоречило бы цели Java.
Это вопрос предпочтений
Суть Java в том, что она разработана, чтобы не дать вам выстрелить себе в ногу. Благородное дело, но со всеми ограничениями, которые оно связывает с вами, весьма вероятно, что вы споткнулись о одну из ваших безопасных ног, не можете взять себя в руки, связав руки за спиной, для вашей собственной безопасности и, наконец, умереть, потому что ты сломаешь свой череп. : D
В некотором смысле, Java была ответом на C ++, который дает вам достаточно веревки, чтобы повесить не только себя, но и весь остальной мир. Это все та веревка, которая делает ее такой привлекательной для ковбоев. Вся эта свобода и вся эта сила.
Проще говоря, это действительно просто вопрос предпочтений.
Но суть в том, что с C ++ в качестве альтернативы Java вы можете сами выбирать свои ограничения. Или действительно сойти с ума со всем вашим контролем, рискуя совершенно запутать ваших сверстников:
По этой причине Java решила не предлагать перегрузку операторов. Конечно, это не позволяет людям запутывать свой код, умножая указатели функций на списки. Но в то же время это мешает другим людям выполнять геометрические / алгебраические вычисления с обычными операторами.
(v1 * v2 / scale) + (v3 * m)
на самом деле намного яснее, чемv1.multiply(v2).divide(scale).add(v3.multiply(m))
. Я понимаю, почему это может оттолкнуть людей, которые занимаются трехмерной графикой и расчетами.Java решила навязать сборку мусора, тогда как в C ++ вы можете выбрать. Вы можете действительно копать весь путь вниз и приблизиться к оборудованию. Вы можете плотно упаковать данные в структуры. Вы можете выполнять темную магию, такую как быстрый обратный квадратный корень . Вы можете выполнить некоторые из самых запутанных и загадочных метапрограммирований на земле, используя шаблоны. Но это также означает, что вы можете потеряться и часами отлаживать весь созданный беспорядок или просматривать абсолютно бесполезные ошибки компилятора.
Но если у вас есть дисциплина, позволяющая использовать только те части языка, которыми вы действительно владеете, вы можете писать код на C ++ так же безопасно, как и код Java, но у вас есть возможность постепенно продвигаться вперед.
Таким образом, хотя технически ничто не мешает вам писать самые современные программы на Java, вы обнаружите, что многие разработчики действительно увлечены написанием отличного программного обеспечения, развлекаясь и разворачиваясь при этом, выходя за рамки того, что Java может предложить как язык.
Но мир состоит не только из тех людей, которые намеревались создать следующую большую вещь, или только из людей, которые будут ограничивать использование предоставленной им власти только в той степени, в которой они ее контролируют. ИМХО Java идеально подходит для людей, которые хотят получать стабильные результаты комфортным способом.
источник
Сборка мусора это большая вещь. Время от времени GC блокирует все остальное на несколько сотен миллисекунд (в зависимости от размера кучи) и создает большую коллекцию. Это хорошо, если у вас нет каких-либо временных ограничений, но если опоздание означает сбой, это остановка показа. Вы можете потратить деньги на Java в реальном времени и ОС реального времени, но вы можете просто использовать GCC и стандартный Linux, и у вас не будет этих проблем.
Без непредсказуемых случайных пауз Java, вероятно, достаточно быстр для большинства вещей в наши дни. И если вы тратите месяцы на настройку параметров своего ГХ и т. Д., Может быть, просто возможно, вы можете заставить его работать достаточно долго, чтобы клиент мог выписать вам чек.
источник
3) Недостатки, которые были исправлены.
Несколько лет назад на Java было много гнева. Большинство Java-программистов - веб-серверные программисты, и они сходили с ума от многословия Java. Поэтому некоторые языки, такие как Ruby, стали популярными, а Java начала угасать. Однако благодаря новым аннотациям и фреймворкам, таким как hibernate и Spring, люди перестали жаловаться и вернулись на Java.
4) Текущие недостатки
Аппаратное обеспечение все собирается многоядерным. Хотя Java может выполнять многопоточность, она основана на C, который является последовательным языком, и функциональность для его многопоточности, по меньшей мере, не элегантна. Кстати, это не просто критика Java, но в значительной степени всех языков. Необходим совершенно иной способ мышления кода. Возможно, функциональное программирование - это путь будущего.
источник
Я как бы отреагировал на этот вопрос, потому что он даст вводящие в заблуждение и в значительной степени нерелевантные ответы:
Каждый может согласиться с тем, что названия AAA было бы сложно создать с использованием Java, и что я не знаю реальных примеров. Однако, учитывая природу AAA, которая предполагает много вещей (поскольку это действительно запутанный термин, возникающий в маркетинге), поэтому лучше спросить следующее:
Ответ: « Да, вы можете ». Однако фактическая часть успеха в уравнении больше основана на вашей настойчивости и удаче (или приверженности духу времени), но это выходит за рамки данного сайта.
источник
Определенная область скорости сводится к компилятору против компилятора. Не язык против языка. Компиляция JIT может иметь преимущества, так как она может оптимизировать под спецификацию машины, на которой она работает. Сравните JIT скомпилированный C ++ против Java, чтобы сравнить компилятор «яблоки с яблоками».
Но есть некоторые вещи, где сам язык Java ограничивает его собственную производительность.
распределение в стеке. Ява не может этого сделать. Для небольших классов фиксированного размера в нерекурсивном решении это часто идеально. Вы также можете избежать фрагментации кучи.
не виртуальные функции. Ява не может этого сделать. Все вызовы методов получают постоянное попадание, даже если они не планируются для переопределения.
Возможно, что-то еще, но это все, что я могу придумать.
источник
1) неактуально и аргументировано для загрузки.
Мало того, что основные части программного обеспечения могут быть созданы на Java, такие системы поставляются каждый день и в настоящее время работают в большинстве крупных компаний мира.
2) То же самое.
Прочитайте спецификацию JVM, и вы знаете. Ява никогда не была интерпретируемым языком.
3) То же самое.
Прочитайте 15-летние заметки о выпуске. Мы не можем понять, что вы считаете «серьезными недостатками», которые необходимо устранить.
4) То же самое.
Основным недостатком, который необходимо устранить, является JCP, который склонен вмешиваться в базовый язык и библиотеки без единой очевидной причины, кроме как получить имя Сомоена в JSR, чтобы они могли написать книгу с авторской ошибкой, что «они были лидер JSR-666 ". Надеюсь, что реструктуризация Oracle JCP позаботится об этом.
Похоже, вы просто хотите разжечь языковую войну и получить подтверждение своих предубеждений против Java, потому что вы сами не можете найти никакого реального оправдания этому.
источник