Что быстрее java или c
Перейти к содержимому

Что быстрее java или c

  • автор:

Производительность C++ vs. Java vs. PHP vs. Python. Тест «в лоб»

/update/ Статья обновлена по результатам обсуждения. Поправлен код Python (около 40% ускорения), написан код на Perl и Ruby (но меня терзают смутные сомнения, что с ruby я что-то сделал неправитьно), поправлен код на Java (на моей машине корректнее тестировать int, а не long. к тому же int в Java эквивалентен long в C++).

Вопрос производительности (скорости работы) различных языков часто всплывает в комментариях, на форумах, часто необоснованные :). Встречаются статьи, в которых авторы приводят примеры, где выигрывает реализация на том или ином языке.

После прочтения очередной статьи мне захотелось самому разобраться «здесь и сейчас». Сначала захотелось сравнить Java и C++ (не верил я, что в вычислительных тестах ява может догнать и обогнать cpp). 10 минут и простой код на C++ и яве готов: простой цикл и математические операции. После написания теста подумал и перевёл их на php и python. Позже добавился код на perl и ruby.

Итак, пару слов о тесте:
Алгоритм синтетический, долгий цикл (двухуровневый) и в нём вычисление математического выражения. Таким образом оценивается вычислительная производительность самого языка (интерпретатора или скомпилированного кода), никаких привязок к качеству реализации тех или иных библиотек, никаких внешних сервисов, никаких системозависимых операций (диск, сеть, графика).

1) Мне нравится ява и я честно предполагал, что результаты будут лучше. Обновлено: long в 64-х битных системах работает значительно быстрее. При работе с int в 32-х битных системах Java значительно ускоряется (на моей машине быстрее, чем C++, видимо, JVM оптимизирует исполнение по умолчанию)
2) Я догадывался, что php будет медленней C++ и Java, но не думал, что он окажется быстрее Perl.
3) Предполагал, что Python будет сопоставим с PHP, но ошибся. Видимо, стандартная поставка PHP лучше оптимизирует исполнение кода.
4) Я совсем не знаком с Ruby, код взят из одного из комментариев. Причём использован код 1, так как у меня он работает быстрее чем код 2. Возможно, это также связано с тем, что у меня 32bit-система.
5) Я достаточно уважительно отношусь к различным языкам программирования, эта статья ни одним из углов не нацелена на разжигание холиваров. Каждый язык имеет свою нишу и своих поклонников.

Тесты запускались по 5 раз минимум, чтобы избежать случайных всплесков. Запускались из консоли и как «nice -n -9», то есть с максимальным на данный момент приоритетом в системе.

Чтобы не заставлять вас читать всю статью, сразу приведу краткие результаты.

Диаграмма (обновленная):

Старый вариант здесь
На диаграмме слолбец с Ruby частично прозрачен по причине того, что на моей машине скрипт Ruby исполнялся неприлично долго, в то время как в комментарии указано, что скрипт исполняется в 4 раза быстрее скрипта на Python — я в замешательстве.
Столбец с Python прозрачен, так как при включении psyco скрипт ускоряется более чем в 10 раз. Проверил на своей машине. Но это, с моей точки зрения, хак, не отражающий собственную производительность языка.
Столбец с PERL, как могут заметить старожилы, теперь идёт вровень с Python 2.6. Причиной этому послужила смена кода с C-подобного синтаксиса на использование range. Дополнительную производительность (около 12%) можно получить использовав директиву «use integer;», но это, по-моему, тоже хак.

В виде таблицы (тоже обновлённой):

Язык Java Java -server C++ C++, -O2 PHP Python 2.6 Python 3.1 Perl 5.8 Ruby 1.8 Ruby 1.9(?)
Время исполнения, сек 5,3 2,8 8,5 2,6 62 91 145 91 207 ~30
Производительность, % 160 303 100 327 14 9 6 9 4.11 28

Время исполнения — на P4-1.8Ггц.
Производительность — относительно производительности базового кода на C++.

Добавлен столбец с запуском Java-кода с ключём «-server». После перехода с «long» на «int» (повторюсь, int в java такой же как и long в c++ на 32bit-arch) он начал давать прирост в производительности почти вдвое.
Столбец с Ruby 1.9 на моём железе не тестировался, результат перенесён через сравнение с производительностью Python’а на той же машине.

И, чтобы не быть голословным, тестовый код.

Java, Test01.java (int в Java то же что и long в C++):

package ru.dchekmarev.test.performance;
public class Test01 public static void main(String[] args) // long start = System.currentTimeMillis();
int r = 0;
for ( int i = 0; i < 10000; i++) for ( int j = 0; j < 10000; j++) r = (r + (i * j) % 100) % 47;
>
>
System.out.println( «answer: » + r);
// закомментировано, т.к. замеры делаются из командной строки
// System.out.println(«run time (millis): » + (System.currentTimeMillis() — start));
>
>

Python, Test01.py (вынос кода в функцию ускоряет работу кода почти вдвое, отдельная же инициализация range() на моей машине даёт порядка 5% производительности):

def test():
r = 0
for i in range(0, 10000):
for j in range(0, 10000):
r = (r + (i * j) % 100) % 47
test()
print ( «answer: » , r)

Perl, Test01.pl (обновлено, с range работает на 25% быстрее против c-подобного синтаксиса for):

$r = 0;
# старый вариант, C-подобный синтаксис
# for ($i = 0; $i < 10000; $i++) # for ($j = 0; $j < 10000; $j++) <
for my $i (0..9999) for my $j (0..9999) $r = ($r + ($i * $j) % 100) % 47;
>
>
print «answer: $r\n»;

Вот здесь приведён красивый пример на Perl, но, мне кажется, такой вариант уже слишком специфичен.

r = 0
for i in 0..10_000 do
for j in 0..10_000 do
r = ( r + ( i * j ) % 100) % 47
end
end
puts «answer: #»

Вот здесь в комментариях обсуждают решение на erlang.

Как видите, ничего сложного: два цикла и математическое выражение. Вычислительная задача в чистом виде.

мой оригинал — там старая версия статьи, а также информация об версиях использованного ПО и результаты тестов из консоли.

Ещё раз повторюсь: каждый язык имеет свою нишу, своих поклонников и свои задачи, с решением которых он справляется лучше других.

PS: а вообще, нет смысла загоняться и меряться чем бы то ни было, производительность самого языка важна для достаточно узкого круга задач, т.к. в общем случае, системы, библиотеки и прочая обвязка нынче несоизмеримо тяжелее самой вычислительной задачи.

Java vs. C#: какой язык лучше учить?

Может быть, вы только начинаете заниматься разработкой программного обеспечения и учитесь программировать (и задаетесь вопросом, с какого языка начать ), или сравниваете два языка друг с другом, чтобы продвинуться по карьерной лестнице. В какой-то момент вы можете задаться вопросом, что вам следует изучать: C# или Java. Где бы вы ни находились в своем путешествии по программированию, мы поможем вам увидеть различия между C# и Java с помощью этого руководства.

C# и Java являются императивными языками общего назначения ( парадигма программирования , в которой используется оператор, изменяющий состояние программы). Давайте изучим два языка и взвесим различия C# и Java.

На высоком уровне, в чем разница между Java и C Sharp?

  • Java основан на классах и объектно-ориентирован, тогда как C# является объектно-ориентированным и компонентно-ориентированным.
  • Java не поддерживает такие функции, как перегрузка операторов и указатели, в отличие от C#.
  • И C#, и Java являются высокоуровневыми объектно-ориентированными языками общего назначения с сильными сообществами.

Что такое С#?

C# — это объектно-ориентированный язык программирования общего назначения, разработанный Microsoft в 2000 году в рамках инициативы .NET. Особенности включают в себя строго типизированность, универсальность, объектно-ориентированность и компонентно-ориентированность. C# разработан на основе стандартов CLI (Common Language Infrastructure). Это популярный язык программирования для начинающих .

C# преследовал следующие цели:

  • Язык задуман как современный, простой, объектно-ориентированный язык программирования.
  • Реализации C# поддерживают принципы разработки программного обеспечения, такие как проверка границ массива, сборка мусора и многое другое.
  • Язык обеспечивает переносимость и, следовательно, может выполняться на разных платформах.
  • C# обеспечивает поддержку интернационализации.
  • Приложения как для встраиваемых систем, так и для ОС поддерживаются C#.

Но похож ли C# на Java? Давайте коснемся еще нескольких функций, прежде чем сравнивать их.

  • Андрес Хейлсберг разработал C# в 1999 году.
  • Первоначально язык назывался «Cool», что означало C-подобный объектно-ориентированный язык.
  • Название C# было вдохновлено нотной записью, а также использовалось Microsoft в 1988 году для незавершенного проекта.
  • В ноябре 2005 года был выпущен C# 2.0 с добавлением дженериков.

Возможности С#

  • Унаследован от C++ и Java.
  • Часть Microsoft Visual Studio.
  • Простой
  • Никаких указателей.
  • Нет таких операторов, как «::» или «->».
  • Различные диапазоны примитивных типов
  • Управление памятью и сборка мусора выполняются автоматически и не требуют явного кода.
  • Современный
  • Построен в соответствии с современным трендом
  • Мощный, масштабируемый, надежный
  • Любой компонент можно превратить в веб-сервис со встроенной поддержкой
  • Объектно-ориентированный
  • Поддерживает концепции ООП, такие как наследование, инкапсуляция, полиморфизм, интерфейсы и т. д.
  • Вводит структуры, позволяющие примитивным типам становиться объектами.
  • Безопасный тип
  • Не позволяет нам небезопасные броски
  • Ссылочные типы инициализируются значением null; типы значений автоматически инициализируются компилятором нулем.
  • Массивы проверяются на привязку и индексируются с нуля.
  • Совместимость
  • Включает встроенную поддержку приложений COM и Windows.
  • Компоненты VB NET можно напрямую использовать в C#.

Что такое Java?

Java — это основанный на классах объектно-ориентированный мультипарадигмальный язык, разработанный Sun Microsystems и разработанный Джеймсом Гослингом в 1995 году.

Он был разработан с использованием концепции WORA (Write Once Run Anywhere) и, таким образом, является независимым от платформы языком. Java-приложения компилируются в байт-код, который может работать на любой JVM независимо от базовой ОС и архитектуры. Приложения могут быть выпущены для веб-разработки, программного обеспечения на базе Android и других устройств.

Приложения Java высокого уровня включают встроенные системы, настольные приложения и серверные приложения. Java поддерживает такие устройства, как смартфоны, банкоматы, домашние системы безопасности и многое другое.

Основные цели Java:

  • Простой и объектно-ориентированный
  • Надежный и безопасный
  • Высокая производительность
  • Интерпретируемый, многопоточный и динамический

История Явы

  • Инициировано в июне 1991 г.
  • Изначально разработан для интерактивного телевидения.
  • Первоначально назывался «Дуб» в честь дуба возле офиса Гослинга.
  • Позже был назван «Зеленым», а затем, наконец, назван Явой, вдохновленным кофе в Индонезии.
  • В 1996 году Sun Microsystems выпустила Java 1.0 (первую версию).
  • В 1998 году была выпущена версия 2 Java с несколькими конфигурациями.
  • В 2006 году Sun переименовала версии J2 в Java EE, Java ME и Java SE.
  • В ноябре 2006 года Sun выпустила JVM (виртуальную машину Java).

Особенности Java

  • Простой: он прост в освоении и имеет простой синтаксис.
  • Объектно-ориентированный: следует концепциям ООП, таким как наследование, абстракция, полиморфизм и инкапсуляция.
  • Надежность: Java предлагает управление памятью и ошибочно обработанные исключения с помощью автоматического сборщика мусора и обработки исключений.
  • Независимая от платформы : она следует своей функциональности WORA, запуская свои приложения на любой платформе с помощью JRE (Java Runtime Environment).
  • Безопасность : стабильные функции Java помогают нам разработать систему, защищенную от вирусов и несанкционированного доступа.
  • Многопоточность . Многопоточность Java позволяет программе выполнять несколько задач одновременно. Таким образом, он использует одну и ту же память и другие ресурсы для одновременного выполнения нескольких потоков.
  • Архитектурно-нейтральный : компилятор генерирует байт-коды, которые не зависят от архитектуры компьютера.
  • Высокая производительность . Когда дело доходит до производительности C# и Java, Java выигрывает. Он обеспечивает высокую производительность благодаря своевременному компилятору.
  • Распределенные: программы могут быть разработаны для работы в компьютерных сетях.

C# против Java: сходство между C# и Java

  • Объектно-ориентированный: оба языка являются объектно-ориентированными и, следовательно, поддерживают такие концепции, как инкапсуляция, полиморфизм, наследование и многое другое.
  • Зависимость от C и C++: C и C++ являются надмножеством как Java, так и C#.
  • Генерация кода промежуточного языка: компиляторы Java и компиляторы C# генерируют код промежуточного языка после компиляции. Компилятор C# генерирует Microsoft Intermediate Language (MSIL), тогда как компилятор Java генерирует байт-код Java.
  • Расширенные функции: оба языка включают расширенные функции, такие как сборка мусора.
  • Синтаксис: Оба языка синтаксически похожи.
  • Множественное наследование: оба языка поддерживают множественное наследование классов.

Ключевые различия между C# и Java

  • Среда выполнения: Java работает в JRE (среда выполнения Java), тогда как C# работает в CLR (среда выполнения общего языка).
  • Парадигма программирования: Java — строго объектно-ориентированный язык, тогда как C# — объектно-ориентированный, функциональный, строго типизированный и компонентно-ориентированный.
  • Перегрузка операторов: Java не поддерживает перегрузку операторов, тогда как C# поддерживает перегрузку операторов для нескольких операторов.
  • Указатели: Java не поддерживает указатели, тогда как C# поддерживает указатели только в небезопасном режиме.
  • Массивы: массивы Java — это специализация Object, а массивы C# — специализация System.

Прямое сравнение между Java и C#

В приведенной ниже таблице сравниваются два языка на высоком уровне, чтобы помочь вам понять основное различие между C# и Java.

Преимущества и недостатки Java по сравнению с C#

Преимущества С#

  • C# обеспечивает поддержку лямбда-выражений и дженериков.
  • Интегрированный в язык запрос (LINQ)
  • Безопасные методы расширения
  • Свойства с методами получения/установки
  • Управление памятью
  • Лучшая в своем классе кроссплатформенная поддержка
  • Обратная совместимость

Недостатки С#

  • Плохой графический интерфейс
  • Должен быть основан на Windows (C# является внутренней частью платформы .NET)
  • Программное обеспечение является собственностью; требует предварительной покупки.
  • В основном зависит от .Net framework; менее гибкий.
  • Выполняется медленно, и программу необходимо компилировать каждый раз, когда вносятся изменения.

Преимущества Java

  • Предоставляет подробную документацию
  • Предлагает большой пул квалифицированных разработчиков
  • Позволяет разрабатывать стандартные программы и повторно используемый код
  • Предлагает многопоточную среду
  • Отличная и высокая производительность
  • Огромный массив сторонних библиотек
  • Удобная навигация по библиотекам

Недостатки Java.

  • Компилятор JIT замедляет работу программы.
  • Java требует высоких требований к памяти и обработке.
  • Язык не обеспечивает никакой поддержки низкоуровневых программных конструкций, таких как указатели.
  • Пользователь не может контролировать сборку мусора, поскольку Java не предоставляет таких функций, как delete() или free().

Заключение

Это завершает сравнение C# и Java, включая обзор языков, их историю как языков программирования , их сходства и различия.

Мы оставим вас с кратким обзором C$ по сравнению с Java:
Выбирайте C#, когда:

  • Вы хотите разрабатывать программы на платформе .NET.
  • Вас интересуют современные функции повышения качества жизни, такие как сбор мусора.
  • Вам нужно, чтобы ваше программное обеспечение работало быстро и эффективно.
  • Вы создаете мобильные приложения или игры.

Выбирайте Java, если:

  • Вы хотите воспользоваться яркой и обширной кодовой базой и сообществом.
  • Вам больше нужна портативность и функциональная совместимость, чем скорость или эффективность.
  • Вам необходимо создавать параллельные веб-приложения или настольные или серверные приложения.

Часто задаваемые вопросы

C# лучше, чем Java?

Споры между C# и Java ведутся давно, и нет явного победителя. Оба языка имеют свои плюсы и минусы, и правильный выбор зависит от ваших конкретных потребностей и предпочтений. Для разработки мобильных приложений и игр обычно предпочтительнее использовать C#.

C# очень похож на Java?

Да, C# очень похож на Java. Оба языка являются объектно-ориентированными, статически типизированными и имеют схожий синтаксис. Однако между этими двумя языками есть некоторые важные различия. C# — это язык Microsoft, а Java принадлежит Oracle. Это существенное различие между C# и Java приводит к различиям в поддержке платформ и инструментарии.

Почему C# быстрее, чем Java?

C# обычно считается быстрее, чем Java, хотя разница незначительна. Оба языка компилируются, но C# использует своевременный компилятор, а Java использует опережающий компилятор. Это означает, что код C# обычно выполняется быстрее.

C# скопирован с Java?

C# не скопирован с Java, но на него сильно повлиял C++, на который повлияли C и Java. Эти два языка похожи, но у них разное происхождение и приложения, несмотря на то, что оба являются объектно-ориентированными языками общего назначения.

C# ближе к C или Java?

C# ближе к C, чем к Java. Это связано с тем, что C++ (находящийся под влиянием как C, так и Java) является языком, на котором первоначально был основан C#. Однако с тех пор C# отошел от C++ и теперь больше похож на Java, чем на C.

Что есть в C#, чего нет в Java?

В C# есть несколько функций, которых нет в Java, включая перегрузку операторов, вывод типов и типы, допускающие значение NULL. В C# также есть LINQ (Language Integrated Query), который является мощным инструментом для манипулирования данными.

Легко ли перейти с C# на Java?

Эти два языка похожи. Если вы знаете один, вы можете легко научиться. Тем не менее, между двумя языками есть некоторые важные различия, о которых вы должны знать, прежде чем переключаться. Шпаргалка может помочь!

Будьте первыми в курсе последних новостей о HR-сфере и IT-рекрутменте — подписывайтесь на наш блог в Telegram!

Java против C#: какой язык производительнее в реальных проектах?

Java против C#: какой язык производительнее в реальных проектах?

Сегодня мы познакомимся с одним опытом, при помощи которого усердный автор, Джефф Когсвелл, попытался рассмотреть производительность кода Java и C# «в реальных условиях». Этот опыт можно считать приглашением к анализу производительности двух языков, ведь полученные автором результаты не претендуют на абсолютную объективность. Но, учитывая соперничество и популярность затронутых в статье языков, надеемся, что материал станет для читателя вкусной пищей для размышлений.

Автор подготовил специальные тесты и решил проверить, какой из этих языков окажется лучше «в реальных условиях»

Давайте сравним Java и C# — два языка программирования, каждый из которых имеет широкий круг поклонников, но вместе с тем и яростных противников. Несмотря на все те прения, которые разворачиваются в онлайне, сложно найти четкие критерии, позволяющие оценить реальную производительность каждого из этих языков.

Какой смысл я вкладываю в понятие «реальный»? Дело в том, что меня не интересует еще один тест, скрупулезно вычисляющий значение числа Пи до миллиона знаков. Я хочу поговорить о решении прикладных задач на языке: какой язык мне выбрать, если требуется ежедневно выдавать клиентам миллионы веб-страниц? Какой из языков сильнее при выборке информации из базы данных и динамической сборке веб-страниц? Именно такая статистика обычно интересует технического специалиста, выбирающего подходящую платформу.

Прежде чем перейти к тестам, давайте определимся с терминологией. Когда вы пишете код Java, вы обычно планируете использовать его на виртуальной машине Java (JVM). Иными словами, ваш код компилируется в байт-код, а этот байт-код работает под управлением JVM. C#, в свою очередь, обычно работает в общеязыковой исполняющей среде (CLR) от Microsoft. C#, как и Java, компилируется в байт-код.

Java и C# — это просто языки. Теоретически вы могли бы писать код Java для исполняющей среды Microsoft CLR, а также код C# для JVM. Действительно, на работу с виртуальной машиной Java ориентирован и ряд других языков, в частности Erlang, Python и др. Самые распространенные языки, рассчитанные на работу с CLR (кроме C#), — собственный язык Microsoft Visual Basic.NET, а также майкрософтовская разновидность C++, называемая C++.NET. Общеязыковая исполняющая среда также поддерживает некоторые менее распространенные языки — уже упомянутый выше Python и F#.

Две эти исполняющие среды содержат фреймворки, представляющие собой наборы классов. Такие наборы для JVM были написаны в Oracle/Sun, а для CLR — в Microsoft. У Oracle есть платформа Java с разнообразными API. Фреймворк Microsoft .NET — это огромный набор классов, обеспечивающих разработку для CLR. На самом деле, многие специалисты называют всю систему просто .NET, а не CLR.

Мы не будем сравнивать языки как таковые. Нас интересуют лежащие в их основе исполняющие среды. Но мы заинтересованы не только и не столько быстродействием этих сред, сколько производительностью фреймворков. Поэтому я выполню несколько сравнений, но в итоге нам все равно придется соотнести яблоки с яблоками.

Например, вы вполне можете написать собственный HTTP-слушатель на C# или Java, а потом просто отправить клиенту динамически сгенерированную HTML-страницу. Но на практике почти никто не пишет низкоуровневых HTTP-слушателей; обычно мы стремимся использовать имеющиеся HTTP-серверы. Большинство веб-приложений на C# работают на базе майкрософтовского сервера IIS.

C другой стороны, серверный код на Java может работать с несколькими разными серверами, в частности Apache HTTP и Tomcat. Кстати, сервер Tomcat был специально разработан для взаимодействия с серверным кодом Java. Мы, конечно, хотели бы сравнивать сопоставимые величины, но в то же время должны сохранить реалистичность эксперимента. Скорее всего, отклик будет зависеть от сервера, а одни серверы работают быстрее других. Хотя HTTP-серверы технически и не входят в состав исполняющей среды, они применяются практически всегда, поэтому их производительность нельзя не учитывать. В первом тесте мы обойдемся без этих стандартных инструментов, а напишем собственные небольшие HTTP-серверы. Во втором случае мы опробуем подобные тесты с аналогичными HTTP-серверами, чтобы получить более точную и полную картину.

Еще одна проблема — это статические файлы, я собираюсь обойтись в данном опыте без них. Некоторые читатели могут со мной не согласиться, но при современных архитектурах, если вам требуется высокая скорость работы со статическими файлами, написанными на JavaScript или CSS, их просто можно загрузить на облачный сервер, данные которого тиражируются во всей стране. Далее по DNS-конфигурации определяем, какой сервер расположен ближе всего к клиенту, и отсылаем данные весьма быстро. Именно поэтому я собираюсь пропустить эту часть. Вдобавок, если вас интересует максимальная производительность, вы не будете нагружать ваше веб-приложение выдачей статических файлов, а постараетесь выполнять в нем только самую необходимую работу: считывание баз данных, сборка динамического контента и т. п.

Замечание об аппаратном обеспечении

Я хочу гарантировать, что применяемое в тестах оборудование привносит в опыт минимальное количество посторонних переменных факторов. На той машине, где я занимаюсь разработкой, стоит масса дополнительных программ, в частности многочисленные сервисы, которые запускаются автоматически и отхватывают процессорное время. В идеале следовало бы выделить под процесс Java или C# целое процессорное ядро, но, к сожалению, выделение ядер происходит иначе. Вы можете ограничить зону действия процесса одним ядром, но не можете «не допустить» в это ядро другие процессы. Поэтому я выделяю для опыта крупные серверы на Amazon EC2, системы которых можно считать базовыми. Поскольку здесь мы не собираемся сравнивать Linux и Windows, а C# ориентирован преимущественно на Windows (если не учитывать проект Mono, который мы и не будем учитывать), все тесты будут выполнены в Windows.

С клиентской стороны требовалось обеспечить, чтобы результаты не искажались из-за сетевых задержек. Единственная задержка могла испортить итоги всего теста. Поэтому я решил исполнять клиентский и серверный код на одной и той же машине. Итак, я не могу «заставить» операционную систему выделять по ядру на процесс, но могу заключить каждый процесс в своем ядре, что я и сделал.

Сбор результатов

Результаты хронометрировались на клиентской стороне. Делая это, лучше всего отследить время и сохранить его, потом по мере необходимости снова отмечать время, и так до конца теста. Лишь по окончании работы выполняются все подсчеты. Кроме того, я не выводил на консоль никаких данных до полного завершения теста. Распространенная ошибка, которую совершают в подобных тестах: в определенных точках отбираются значения времени, в каждой точке подсчитывается разница во времени, после чего результаты выводятся на консоль. Консоли работают медленно, особенно если их требуется прокручивать. Итак, работаем до конца, а потом вычисляем разностные значения и выводим данные на экран.

Клиентский код

Фактически неважно, какой код мы используем в качестве клиентского — важно последовательно задействовать его во всех тестах. Клиентский код будет имитировать работу браузера и измерять, сколько времени требуется на доставку страницы с сервера. Для этого можно использовать C# или Java. Я остановился на C#, поскольку в нем есть очень простой класс WebClient и несложный класс-таймер.

Первый тест: слушание HTTP

Начнем. Мы протестируем код, который просто открывает HTTP-слушатель и рассылает динамически сгенерированные веб-страницы.

Сначала попробуем Java. Мы можем реализовать описанную задачу несколькими способами, но я хотел бы обратить внимание на два подхода. Во-первых, попробуем открыть слушатель TCP/IP на порте 80 и дождаться входящих соединений. Это очень низкоуровневый метод, при котором мы будем пользоваться классом Socket. Другой интересующий нас вариант — использование класса HttpServer. Вот почему я собираюсь воспользоваться этим классом: если мы действительно хотим сравнить скорость Java и C#, без участия Веба, то можно применить некоторые базовые индикаторы, не связанные с работой в Интернете. Так, можно написать два консольных приложения, которые будут оперировать подборкой математических уравнений и, возможно, также выполнять кое-какой строковый поиск и конкатенацию — но это уже другая история. Здесь нас интересует Веб, поэтому займемся HttpServer и его эквивалентом на C#.

Сразу же я обнаружил одну аномалию: выполнение любого запроса в Java-версии длится почти в 2000 раз больше. На обработку 5 запросов при получении строки из CLR-программы, использующей класс HttpListener, ушло около 17 615 тактов процессора, а на 5 аналогичных запросов с применением сервера Java и класса HttpListener было израсходовано 7 882 975 тактов. Если выразить это соотношение в миллисекундах, то имеем 2 миллисекунды на 15 запросов на сервере C# и 4045 миллисекунд на сервере Java.

Добавив на сервер Java некоторую отладочную информацию, я выяснил, что сама функция, занятая ответами на входящие запросы и рассылкой данных, работает довольно быстро — ни разу не приближаясь даже к показателю в 3 секунды. Вероятно, узкое место расположено где-то во фреймворке Java, при отправке данных обратно к клиенту. Но такая проблема отсутствует при обмене информацией с клиентом C#.

Чтобы докопаться до сути проблемы, я решил перейти на другой Java-клиент. Отказался от сравнительно тяжеловесного класса HttpServer, а взамен создал простой сокет, слушающий TCP/IP — для этого воспользовался классом ServerSocket. Вручную создал строку заголовка и основной текст, совпадающий с отправленным в версию на C#.

Ситуация значительно улучшилась. Могу запускать множество тестов; выполняю 2000 запросов один за другим, но не собираю данных о времени, пока не завершатся все 2000 вызовов к серверу Java. Потом осуществляю аналогичный процесс с сервером C#. В данном случае время измеряется в миллисекундах. На 2000 запросов к серверу Java уходит 2687 миллисекунд. На 2000 запросов к серверу на C# тратится 214 миллисекунд. C# по-прежнему гораздо быстрее.

Поскольку сохраняется такая значительная разница, мне ничего не оставалось, кроме как испробовать версию Java на сервере Linux. Я воспользовался сервером «c1.medium» на Amazon EC2. Установил оба упомянутых класса Java и получил фактически такие же скорости. Класс HttpServer тратит около 14 секунд на обработку 15 запросов. Плоховато.

И, наконец, чтобы быть абсолютно уверенным, я написал на Java эквивалентную клиентскую программу, получающую данные. Временные показатели существенно не изменились.

Второй тест: полнофункциональный сайт

Как я уже указывал, мы редко пользуемся самодельными HTTP-серверами. Программисты, работающие с C#, обычно прибегают к IIS. У приверженцев Java есть несколько вариантов, в частности, Tomcat. В моих тестах я использовал именно эти два сервера. В варианте с C# я задействовал платформу ASP.NET MVC 4, работающую на IIS 8. Применил два метода: в первом случае возвращал HTML-строку от самого контроллера; во втором — возвращал представление, содержащее справку даты/времени.

В тестах Java можно применять два похожих метода. Можно работать с сервлетом, возвращающим информацию на HTML, либо возвращать результаты на странице JSP. Эти методы аналогичны приемам C#, в первом из которых задействуется контроллер, а во втором — представление. Можно было бы применить более новые Java Faces или любые другие фреймворки; оставляю эти задачи всем заинтересованным для самостоятельного изучения.

Контроллер C# просто возвращает HTML-строку. При прогоне моего клиентского теста с 2000 итераций на него уходит 991 миллисекунда. Опять же, гораздо быстрее, чем версия с сокетом Java.

Та версия приложения C#, которая работает с представлением, создает полнофункциональную HTML-страницу, соответствующую всем стандартам. Здесь есть элементы HTML, head, meta, title, body и внутренний элемент div, содержащий текст «The date and time is» с указанием даты и времени. Дату и время мы получаем в экземпляре DateTime.Now, динамически записывая эту информацию при каждом запросе.

Прогон клиентского теста (2000 итераций) в такой версии с представлением занимает 1804 миллисекунды; примерно вдвое дольше, чем напрямую. Напрямую мы возвращаем более краткий HTML, но если увеличить HTML до размеров, сопоставимых с вариантом-представлением, разница практически отсутствует; длительность колеблется в пределах 950—1000 миллисекунд. Даже при добавлении динамической записи даты и времени процесс существенно не замедляется. В любых условиях версия с представлением выполняется примерно вдвое дольше, чем версия с контроллером.

Перейдем к Java. Сервлет не сложнее, чем контроллер C#. Он просто возвращает строку, содержащую HTML-страницу. На возврат 2000 экземпляров уходит 479 миллисекунд. Это примерно вдвое быстрее, чем с контроллером C# — действительно впечатляет.

Возврат JSP-страницы также происходит очень быстро. Как и в случае с C#, второй вариант протекает дольше первого. В данном случае на возврат 2000 экземпляров расходуется 753 миллисекунды. Если добавить к JSP-файлу вызов, возвращающий дату, заметной разницы не возникает. На самом деле, на сервере Tomcat явно выполняется какая-то оптимизация, так как в последующих попытках на возврат 2000 экземпляров тратится уже 205 миллисекунд.

Заключение

Эти результаты кажутся мне довольно интересными. Я много лет профессионально занимался программированием на C#, мне неоднократно говорили, ссылаясь на личный опыт, что .NET — одна из самых быстрых существующих сред исполнения. Но эти тесты свидетельствуют об обратном. Разумеется, они минимальны; я не делал никаких крупных вычислений, активных запросов к базе данных. Возможно, я еще проведу тесты с базой данных и уточню результаты. Но в моем опыте Java побеждает с явным преимуществом.

Java и C++: тест на быстродействие

В те времена, когда все виртуальные машины Java представляли собой интерпретаторы байт-кода, эта технология вызывала справедливые нарекания за свою низкую производительность. Но по прошествии некоторого времени на рынке появились хорошие компиляторы just-in-time (JIT), и сегодня тесты показывают, что по быстродействию Java во многих областях практически сравнялась с C++. Наметившиеся тенденции позволяют надеяться на то, что уже в самое ближайшее время Java не уступит в скорости C++.

Как соотносится производительность приложений Java и аналогичных программ на C++, максимально оптимизированных по критерию быстродействия? Думаю, что пользователям было бы интересно ознакомиться как с результатами теоретического сравнения, так и с выводами, сделанными на основе анализа тестовых программ и реальных приложений. Большинство аналитиков, не желая углубляться в хитросплетения сложных технологий, с ходу заявляют, что Java всегда будет уступать в производительности другим языкам по причине многоплатформенности Java. Такие утверждения можно встретить во многих статьях, посвященных Java и сетевым компьютерам.

Мы решили провести самостоятельное исследование и выяснить, в чем Java уступает C++ (специалисты любят противопоставлять именно эти два языка). Были изучены компоненты архитектуры Java и определены сравнительные характеристики быстродействия идентичных программ, написанных на Java и на C++.

Мы готовились к тому, что программы Java будут отставать по всем показателям, хотя и не верили, что C++ окажется в несколько раз быстрее. К большому нашему удивлению, какой-либо разницы в производительности практически не ощущалось. В некоторых случаях скорость приложений Java действительно значительно уступала этому показателю у C++, что, впрочем, легко объясняется наличием строгой модели безопасности и издержками технологии «сборки мусора».

Любое повышение производительности какого-либо языка следует рассматривать в строго определенном контексте. С момента появления Java прошло уже немало времени, и это время не было потрачено впустую. Неслучайно сегодня по уровню быстродействия этогот язык в большинстве случаев сравним с C++ (а C++ славится своей высокой скоростью).

КАК ПРОВОДИЛОСЬ ТЕСТИРОВАНИЕ

ЗАГРУЗКА ИСПОЛНЯЕМОГО КОДА

При создании нового приложения разработчики сначала записывают программный код в один или несколько исходных файлов. Компилятор/компоновщик транслирует исходный код в исполняемый. В готовом приложении работает именно исполняемый код. На первом этапе необходимо загрузить исполняемый код в память компьютера. Загрузка исполняемого кода: Java против C++ Если программа находится на локальном диске, загрузка даже сложного приложения не займет много времени. Если же программа хранится на Web-узле в Internet или в корпоративной сети intranet, размер исполняемого кода может существенно повлиять на производительность. Программы и ресурсы Java занимают значительно меньше места на диске по сравнению с программами C++ и загружаются из Internet и intranet гораздо быстрее. При определении скорости загрузки необходимо учитывать размер исполняемого кода и возможность избирательной загрузки. Размер исполняемого кода Исполняемые модули Windows NT, написанные на C++, занимают на диске значительно больше места, чем исполняемые модули Java. На размеры исполняемого кода оказывают влияние три фактора: Во-первых, двоичный формат исполняемого кода C++ увеличивает его размеры по сравнению с кодом Java почти в два раза. Во-вторых, технология Java предусматривает активное использование ряда библиотек, содержащих математические и сетевые функции, классы для работы с составными элементами и графикой и так далее. В виртуальные машины Java (JVM) встроена поддержка этих библиотек. В C++ же, напротив, определяются интерфейсы прикладных программ (API), позволяющие разработчику унифицировать доступ к большинству функций. К сожалению, если программист захочет использовать какие-либо специальные функции, не имея доступа к базовому API C++, ему придется самому реализовывать поддержку библиотек для своей программы. Включение в программу библиотечных функций может удвоить или даже утроить размеры конечного кода. В третьих, в комплект Java входят специальные библиотеки, позволяющие работать с графическими и звуковыми файлами, записанными в сжатом формате. Поддерживаются, в частности, графические форматы Joint Photographic Expert Group (JPEG) и Graphics Interchange Format (GIF), а также аудиоформат AU. Средства разработки программ на C++ для Windows NT поддерживают только несжатые форматы: bitmap (BMP) для изображений и wave (WAV) для аудиофайлов. Сжатие дает возможность на порядок уменьшить размеры графических файлов, и приблизительно в три раза — размеры аудиофайлов. Если вы хотите работать с другими форматами графических и звуковых файлов, можно воспользоваться дополнительными библиотеками классов. Избирательная загрузка Загрузчики программ, написанных на C++, перед началом выполнения должны полностью загрузить исполняемый файл. В среде Win32 имеется два способа связи с библиотеками DLL: статический и динамический. Статически связанные DLL (используемые в большинстве случаев) загружаются до начала выполнения программы. В случае динамического связывания библиотеки DLL загружаются по запросу. Однако такой вариант гораздо менее популярен, поскольку написание кода динамической загрузки и обращения к библиотечным функциям требует от разработчика значительных усилий. Кроме того, не существует способов проверки целостности динамически связанной DLL на этапе выполнения. Это означает, что без аварийного завершения нельзя выяснить, изменялась ли DLL в процессе выполнения программы. Наконец, если программа будет загружаться с удаленного диска, необходимо предварительно скопировать библиотеки на локальный носитель. Реализация такой процедуры в автоматическом режиме потребует дополнительных затрат на программирование. В свою очередь загрузчик Java способен выборочно загружать классы по мере необходимости. Рассмотрим, к примеру, полнофункциональный текстовый процессор со встроенным тезаурусом, орфографическим корректором и средствами создания и экспорта почты. Реализация данных возможностей обычно приводит к генерации многомегабайтного кода. Средний пользователь в любой конкретный момент времени использует лишь малую часть потенциала средств разработки. Если программа была написана на C++, перед началом обработки пользователь обязан загрузить файл полностью. В случае, когда программа написана на Java, на первом этапе в памяти размещается только самое необходимое (например, главное окно), а дополнительные модули подгружаются по мере необходимости. Загрузка исполняемого кода реальных программ В таблице 1 представлены размеры протестированных программ и их ресурсов. Огромная разница между размерами кода C++ и Java объясняется наличием библиотек, необходимых для выполнения программы C++. Объемы ресурсов отличаются вследствие того, что приложения Java работают со сжатыми файлами (в формате GIF), а программы C++ — с обычными файлами bitmap. Таблица 1

Имя программы Размеры программы, Кбайт (C++/Java) Ресурсы, Кбайт (C++/Java)
Simple Loop 46/3,9 -/-
Memory Allocation 34/1,4 -/-
Bouncing Globes 103/21 485/13

ВЫПОЛНЕНИЕ ПРОГРАММНЫХ ИНТСТРУКЦИЙ

После загрузки исполняемого кода процессор начинает выполнять программные инструкции. При традиционном программировании на C++ исполняемый файл содержит двоичные инструкции процессора выбранной платформы. Для переноса приложения на другую платформу разработчику потребуется создать новый исполняемый файл путем перекомпиляции исходного кода. Кроме того, особенности конкретной платформы каждый раз заставляют вносить определенные изменения в исходный код. Исполняемые же файлы, получаемые на выходе компилятора Java, представляют собой совокупность байт-кодов, которые не могут выполняться процессором без дополнительного преобразования в двоичный код. Это преобразование возлагается на JVM. Виртуальная машина Java может осуществлять преобразование двумя способами: с помощью интерпретатора байт-кода или посредством компилятора just-in-time (JIT). Выполнение программных инструкций: Java против C++ У программ, написанных на Java, не слишком хорошая репутация. Их производительность заставляет вспомнит о старых JVM, для которых интерпретация байт-кода была единственным способом выполнения программных инструкций. Интерпретаторы байт-кода работали в несколько раз медленнее исполняемого кода программ C++, поскольку каждую инструкцию в ходе выполнения необходимо было преобразовать в двоичный код. Это, в свою очередь, приводило к неоправданным расходам. Приведем простейший пример. Каждый цикл состоит из набора многократно повторяющихся инструкций. При выполнении очередной итерации JVM снова и снова интерпретирует один и тот же байт-код, при этом на процедуру интерпретации уходит довольно много процессорного времени. Но методы, на которых базировалась работа старых JVM, уже уходят в прошлое. Большинство современных виртуальных машин Java оснащается JIT-компиляторами. Эти компиляторы транслируют и преобразуют в двоичный код сразу весь исходный файл. Таким образом, отпадает необходимость повторной трансляции каждой инструкции байт-кода. Производительность кода различных компиляторов Компиляторы C++ могут повысить скорость выполнения отдельных частей кода путем выявления неэффективных участков и их соответствующего преобразования. Этот процесс носит название оптимизации. К примеру, хороший компилятор способен распознать небрежность программиста и исключить из цикла «статические» вычисления. Под «статическими» вычислениями понимается выполнение в цикле определенной операции, результатом которой независимо от итерации всегда является константа. Распознав такую конструкцию, компилятор выводит ее за рамки цикла. Таким образом, значение константы вычисляется еще до входа в цикл и может использоваться внутри него, сокращая время выполнения и не изменяя логики программы. Этот тип оптимизации называется перемещением выражений. Для его выполнения компилятору необходимо сделать несколько проходов и изучить все инструкции цикла. В приведенном выше примере перемещения выражения все команды цикла должны быть тщательно проверены, и компилятор обязан убедиться в том, что при любой итерации значением выражения является константа. Виртуальная машина Java, не имеющая JIT-компилятора, последовательно интерпретирует каждую инструкцию и не может проводить подобную оптимизацию «на лету». Технология JIT-компилятора позволяет оптимизировать файл классов целиком. Таким образом, единственная причина, по которой обрабатываемая JIT-компилятором программа Java и приложение C++ работают с разной скоростью, — это необходимость первоначальной трансляции файла классов; она же, в свою очередь, зависит от типа проводимой оптимизации. Общее время выполнения программы, включающей в себя большое количество классов, складывается из времени, которое требуется на компиляцию этих классов, и времени обработки процессором двоичного кода. В реальных программах многократно встречаются одни и те же классы, поэтому на практике затраты на компиляцию всегда оказываются значительно ниже затрат на непосредственное выполнение двоичного кода. На начальном этапе большинство компаний, разрабатывавших компиляторы JIT, пытались определять, какие классы следует компилировать, а какие — нет. Это зависело от того, как часто появляются классы в программе. Впоследствии многие производители отказались от такого решения, и компиляторы стали транслировать весь исходный код, поскольку общее время выполнения при этом практически не изменялось. Теория и практика Теоретически скорости выполнения байт-кода Java, обрабатываемого JIT-компилятором, и двоичного кода С++ не должны существенно различаться. На практикеже необходимо учитывать два фактора, оказывающих существенное влияние на производительность. Во-первых, одной и той же инструкции байт-кода могут соответствовать несколько различных последовательностей команд конкретного процессора. В результате выполнения этих последовательностей вы получите один и тот же результат, но время обработки при этом будет заметно отличаться. Если команды, получаемые на выходе JIT-компилятора и компилятора C++, требуют одинакового количества тактов процессора, быстродействие программ Java и C++ оказывается практически одинаковым. (В данном случае все зависит от того, насколько хорошо компилятор оптимизирует исполняемый код по критерию быстродействия.) Во-вторых, имеет смысл оценивать количество проходов компилятора, необходимое для оптимизации отдельных участков кода. В рассмотренном выше примере «статических» вычислений, чтобы определить, изменяется значение выражения или нет, компилятору, возможно, потребуется проверить все итерации цикла. Один из видов более сложной оптимизации — это устранение неиспользуемого кода. В данном случае компилятор должен найти операторы, которые не выполняются ни при каких условиях. Если такие операторы существуют, они не включаются в исполняемый код. Устранение неиспользуемого кода может привести к существенному повышению быстродействия программы, однако при этом значительно увеличивается и время компиляции. Необходимо учитывать, что появление неиспользуемого кода — это результат ошибок программиста. Опытные разработчики обязательно проверяют текст программы на наличие неиспользуемого кода, облегчая тем самым задачу компилятора. В общем случае в зависимости от выигрыша в производительности и временных затрат все виды оптимизации можно разделить на несколько уровней. Первый и второй уровень оптимизации как правило повышают быстродействие на 10-15 % при минимальных затратах. Третий уровень оптимизации позволяет увеличить производительность еще на 5 %, однако это обойдется значительно дороже. Примеры реальных программ В таблице 2 сравниваются результаты выполнения нескольких процедур Java и аналогичных программ, написанных на C++. Нетрудно заметить, что при отсутствии JIT-компилятора производительность Java в три-четыре раза уступает этому показателю для C++. Таблица 2

Тест Описание Время выполнения программы C++, сек. Время выполнения программы Java (JIT-
компилятор), сек.
Время выполнения программы Java (интер-
претатор байт-кода), сек.
Целочисленное деление В цикле 10 тыс. раз выполнялась операция целочисленного деления. 1,8 1,8 4,8
Неиспользуемый код В цикле 10 млн. раз встречалось неиспользуемое выражение 3,7 3,7 9,5
Комбинация неиспользуемого кода и целочисленного деления В цикл была встроена одна исполняемая команда и 10 млн. раз неиспользуемых выражений 5,4 5,7 20
Деление с плавающей точкой В цикле 10 млн. раз выполнялось деление с плавающей точкой 1,6 1,6 8,7
Статический метод В цикле 10 млн. раз вызывался статический метод, реализующий целочисленное деление 1,8 1,8 6,0
Компонентный метод В цикле 10 млн. раз вызывался компонентный метод, реализующий целочисленное деление 1,8 1,8 10
Виртуальный компонентный метод* В данном тесте 10 млн. раз вызывался виртуальный компонентный метод, реализующий целочисленное деление 1,8 1,8 10
Виртуальный компонентный метод с приведением типов и идентификацией типа в момент выполнения (RTTI) В данном тесте 10 млн. раз вызывался виртуальный метод класса, в котором выполнялась операция приведения типов 11 4,3 12
Виртуальный компонентный метод с неправильным приведением типа и идентификацией типа в момент выполнения (RTTI) В данном тесте 10 млн. раз вызывался виртуальный метод класса, в котором выполнялась операция приведения типов -** -** -**

Примечания: * Тест компонентного метода не вполне корректен, поскольку в Java все компоненты являются виртуальными.
** Аварийное завершение В полном соответствии с теоретическими исследованиями быстродействие программ Java, обрабатываемых JIT-компилятором, практически не отличается от этого показателя для процедур C++. Единственное исключение — выполнение операции приведения типов, где скорость C++ значительно превосходит скорость Java. Сложные объектно-ориентированные программы имеют сложную иерархию, вследствие чего часто приходится выполнять операцию преобразования родительского класса в дочерний. Данная операция называется приведением типов. В момент выполнения программы проверяется правильность преобразования родительского класса в дочерний (идентификация типа в момент выполнения — run-time type identification, RTTI). При эксплуатации сложных систем, в которых не реализованы методы RTTI, часто возникают ошибки. Это значительно снижает эффективность всей системы и подрывает доверие пользователей. Большинство программистов, пишущих на C++, отключают RTTI, чтобы повысить быстродействие. Технология Java не позволяет воспользоваться таким приемом, поскольку это может привести к нарушению системы безопасности. Наши тесты еще раз продемонстрировали, насколько методы RTTI замедляют скорость выполнения программы.

РАСПРЕДЕЛЕНИЕ ПАМЯТИ

Для хранения информации и выполнения вычислений программы должны эффективно управлять имеющейся памятью. После того как потребность в ранее выделенной области памяти отпадает, эта память должна быть освобождена и возвращена системе. Механизмы выделения памяти C++ и Java очень похожи. Что касается освобождения, здесь имеются принципиальные отличия. Программы C++ обязаны явно освобождать память. Очень часто при выполнении программ C++ возникают ошибки, вызванные тем, что программист забыл явно освободить память. Эта память «блокируется» и становится недоступной до завершения работы приложения. В среде Java реализован встроенный механизм освобождения памяти, называемый «сборкой мусора». Этот механизм автоматически определяет момент, когда конкретная область памяти больше не нужна программе, после чего память возвращается системе. Распределение памяти: Java против C++ Поскольку «сборщик мусора» Java должен автоматически выявить незадействованные программой области памяти, общие расходы Java на распределение памяти значительно превышают соответствующие расходы C++. Но при этом механизм освобождения памяти Java обеспечивает два очень важных преимущества. Во-первых, программы фактически гарантированы от утери памяти. Поскольку ошибки, связанные с потерей областей памяти, очень часто встречаются в сложных системах, отпадает необходимость поиска таких ошибок и длительного изучения кода с помощью отладчика, а следовательно значительно сокращается цикл разработки. Еще один недостаток сложных систем — фрагментация памяти, возникающая в результате многочисленных операций выделения и освобождения памяти и существенно снижающая скорость выполнения приложения. Хорошо написанный «сборщик мусора» Java способен, эффективно перераспределяя память, предотвратить фрагментацию. Таким образом, Java и C++ используют различные механизмы управления памятью. Эффективность распределения памяти, характерная для Java, достигается за счет снижения производительности. Сложность реализации стратегии «сборки мусора» заключается в том, что механизм освобождения памяти должен самостоятельно выявить неиспользуемые объекты. Если программист твердо придерживается принципов объектно-ориентированной философии, процесс «сборки мусора» обойдется сравнительно недорого. В случае же использования процедурного подхода, сложность взаимосвязей значительно затруднит поиск неиспользуемых объектов. Примеры программ На выделение и освобождение памяти для 10 млн. 32-разрядных целых чисел программе на C++ потребовалось 0,812 сек., а программе на Java — 1,592 сек. На основании данного примера хорошо прослеживается снижение быстродействия Java. И все же несмотря на огромную дополнительную работу, выполненную «сборщиком мусора», производительность Java вполне соизмерима с производительностью C++.

ДОСТУП К СИСТЕМНЫМ РЕСУРСАМ

Помимо распределения памяти программе необходим доступ к другим системным службам, таким как вывод графических примитивов, обработка звука и управление окнами. Традиционные программы на C++ обращаются к системным функциям при помощи интерфейсов прикладных программ (API). Каждой платформе соответствует свой API, поэтому при переносе программы с одной платформы на другую разработчику приходится порой проводить существенные модификации. Программы Java обращаются к системным службам любой платформы при помощи единственного API. Каждая платформа имеет сходные интерфейсы, которые в ответ на обращения Java выделяют программе необходимые ресурсы. Доступ к системным ресурсам: Java против C++ В общем случае преимущества, которые дает однотипное обращение к системным службам, оправдывают стоимость разработки специальных интерфейсов Java. Программы Java, вызывающие системные функции, работают так же быстро, как программы C++. Единственным исключением из этого правила является то, что средства, эквивалентные функциям API Java, имеются не на всех платформах. В частности, операционные системы компьютеров Macintosh не поддерживают потоки, поэтому соответствующие функции API Java невозможно задействовать на платформе Macintosh. Примеры программ Мы протестировали программу, разработанную известным специалистом в области анимации и мультимедиа Джеем Бартотом. Быстродействие реализующего ее алгоритм апплета Java ничем не отличалось от этого показателя программы, написанной при помощи средств Win32 SDK. Данный пример поможет служить подтверждением двух важнейших постулатов. Во-первых, производительность Java зависит от производительности JVM. Тестовая программа, работавшая под управлением Internet Explorer 4.0 и Netscape Communicator в среде Windows NT, не отличалась высокой скоростью выполнения. Объекты перемещались на экране неестественно, с высокой дискретностью. Однако стоило запустить браузеры в среде Windows 95, как скорость анимации стала вполне приемлемой. Разница в производительности объясняется огромной работой, проделанной с тем, чтобы оптимизировать быстродействие браузеров в среде Windows 95. Принципиальные архитектурные различия не позволяют обеспечить одинаковую производительность браузера в обеих операционных системах. Во-вторых, пакет JDK for Win32, разработанный корпорацией Sun, является общепринятым стандартом, который обязаны поддерживать все браузеры и JVM.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *