а. Как скорость 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 ++. Тем не менее, на самом деле нет никакого способа сделать резервную копию каких-либо заявлений о производительности без чрезвычайно всеобъемлющего набора тестов из-за принципиально различных задействованных алгоритмов.
б. Возможно ли создать современное название AAA с использованием Java?
Я предполагаю, что вы имеете в виду «игру», здесь и не случайно. Во-первых, вам придется написать все с нуля, поскольку почти все существующие библиотеки и инфраструктура предназначены для C ++. Хотя это и не делает невозможным само по себе, оно, безусловно, может внести весомый вклад в невозможное. Во-вторых, даже движки C ++ вряд ли могут вписаться в крошечные ограничения памяти существующих консолей - если JVM даже существуют для этих консолей - и геймеры ПК ожидают немного больше для своей памяти. Создание эффективных AAA-игр достаточно сложно в C ++, я не понимаю, как этого можно достичь в Java. Никто никогда не писал игру ААА со значительным временем, проведенным на некомпилированном языке. Более того, это было бы чрезвычайно подвержено ошибкам. Детерминированное уничтожение необходимо при работе, например, с ресурсами GPU, а в Java вы
с. В каких областях конкретно Java медленнее, чем C ++, если вообще? (то есть сокращение чисел, графика или просто все вокруг)
Я бы определенно пошел на все вокруг. Природа принудительных ссылок для всех объектов Java означает, что в Java гораздо больше косвенных ссылок и ссылок, чем в C ++ - пример, который я привел ранее для массивов, но также, например, применим ко всем объектам-членам. Когда компилятор C ++ может искать переменную-член в постоянное время, среда выполнения Java должна следовать за другим указателем. Чем больше обращений вы делаете, тем медленнее это будет, и JIT ничего не сможет с этим поделать.
В то время как C ++ может освободить и повторно использовать часть памяти практически мгновенно, в Java вам придется ждать коллекции, и я надеюсь, что эта часть не вышла из кэша, а по своей природе требуется больше памяти, что означает снижение производительности кэша и подкачки. Затем посмотрите на семантику таких вещей, как бокс и распаковка. В Java, если вы хотите ссылаться на int, вы должны динамически размещать его. Это неотъемлемая трата по сравнению с семантикой C ++.
Тогда у вас есть проблема дженериков. В Java вы можете работать только с общими объектами через наследование во время выполнения. В C ++ шаблоны имеют практически нулевые накладные расходы - что Java не может сопоставить. Это означает, что весь универсальный код в Java по своей природе медленнее, чем универсальный эквивалент в C ++.
И тогда вы приходите к неопределенному поведению. Все ненавидят, когда их программа показывает UB, и все хотят, чтобы ее не было. Тем не менее, UB в основном обеспечивает оптимизацию, которая никогда не может существовать в Java. Посмотрите на этот пост с описанием оптимизации на основе UB. Отсутствие определения поведения означает, что реализации могут выполнять больше оптимизаций и сокращать код, необходимый для проверки условий, которые не определены в C ++, но определены в Java.
По сути, семантика Java диктует, что это более медленный язык, чем C ++.
Считается ли сейчас Java компилируемым или интерпретируемым языком?
Это не вписывается ни в одну из этих групп. Я бы сказал, что управляемый - это отдельная категория, хотя я бы сказал, что это определенно больше похоже на интерпретируемый язык, чем на скомпилированный. Что еще более важно, есть только две основные управляемые системы, JVM и CLR, и когда вы говорите «управляемые», это достаточно явно.
Какие основные недостатки Java были устранены с первых дней?
Автоматический бокс и распаковка - единственное, что я знаю. Дженерики решают некоторые проблемы, но далеко не многие.
Каковы некоторые основные недостатки Java, которые еще предстоит устранить?
Их дженерики очень и очень слабые. Обобщения C # значительно сильнее - хотя, конечно, и не совсем шаблоны. Детерминированное разрушение является еще одним серьезным недостатком Любая форма лямбда / замыкания также является серьезной проблемой - вы можете забыть о функциональном API в Java. И, конечно же, всегда есть проблема производительности для тех областей, которые в них нуждаются.