Что выбрать: Переносимость ++ или Производительность - ?

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

(c) Компьютерная газета


Язык Java - далеко не первый, который основывается на интерпретаторе. Эта идея возникла еще лет двадцать назад. Но производительность тех компьютеров была настолько низкой, что позволить себе дополнительные затраты ресурсов процессора было просто невозможно, поэтому, кроме Basic'а, интерпретатор нигде не использовался.

До конца 80-х. Тогда серьезное применение интерпретируемые языки нашли в области разработки приложений обработки баз данных. Например, dBase и позже FoxBASE/FoxPro. Производительность персональных компьютеров тех времен уже позволяла приложениям на этих СУБД работать достаточно быстро, а сама структура языка позволяла создавать прикладные программы за очень короткий срок (время - понятие относительное;-).

Это была настолько удачная реализация симбиоза интерпретатора и СУБД, что фирмы-производители были моментально раскуплены гигантами индустрии ПО - соответственно, Borland и Microsoft. А сами продукты существуют и развиваются до сих пор.

Главная причина успеха интерпретаторов в этой области ПО заключалась в том, что язык СУБД является высокоуровневым (одна команда заменяет большое множество команд) и проблемным (ориентированным на обработку баз данных).

В этом случае нет прямой зависимости работы программы от скорости преобразования и интерпретации кода, т.к. главные затраты производительности ложатся на чтение/запись БД подпрограммами самой СУБД, реализованными в машинных кодах исполняющей системы. Даже если скорость интерпретатора в 20 раз меньше, чем программы откомпилированной в кодах процессора, а собственные алгоритмы приложения составляют лишь 5% от всех затрат (остальные 95% - чтение/запись БД), то проигрыш в производительности составит чуть более 4 с половиной процентов - практически ничего. А сложность самих программ и уровень временных затрат на разработку уменьшатся также раз в 20. Есть что выбирать.

В самом деле, ОДНА команда FoxPro:

replace all Oklad with Oklad*1.37

выполняющая умножение полей, обработает все записи БД и, таким образом, заменяет целый цикл множества команд того же Delphi, а скорость выполнения для больших баз будет различаться незначительно.

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

Здесь уже есть линейная зависимость скорости работы от скорости интерпретации кода, поэтому выполнения алгоритма Java-программой будет действительно в 10-30 раз медленнее.

Но только в том случае, если сам алгоритм не предусматривает обращение к данным в Internet. Ведь Java, как язык в СУБД, также является проблемным. С момента появления под этим именем он предназначался для обработки информации в Интернет, а так как информация там самая разнообразная, то и язык нужен был низкоуровневый для самой разнообразной обработки. Но сама реализация обращения к данным в Сети выполнена внутри виртуальной Java-машины в кодах процессора.

А главное заключается в том, что время обработки информации на клиентской машине практически всегда будет несопоставимо малым по сравнению со временем доставки этой самой информации по Сети от сервера клиенту и обратно. Например, если сервер доставит на клиентский компьютер данные за 10 секунд, C-программа обработает их за 0.05с, а Java-программа обработает за 1с, то разница в производительности составит (1-0.05) / (10+1) *100% = 8% - Вы ее даже не заметите.

Для таких приложений, так же, как и для приложений СУБД, нет прямой зависимости от скорости интерпретатора. Именно поэтому сравнивать платформу Java с другими нужно по тем возможностям, которые необходимы для реализации Вашего проекта.

А возможностей у Java столько, что никто не боится утверждать - этот язык займет ведущее положение в создании виртуальных магазинов, корпоративных бизнес-приложений и других проектов, основывающихся на работе во Всемирной Сети.

Конечно, можно применять его и для других целей. Для той же анимации на Web-страничках он прекрасно подойдет. Какие-то шутники написали на Java даже эмулятор ZX-Spectrum - работает, хотя это уж слишком.

Увеличить производительность приложения почти всегда можно с помощью оптимизации алгоритма. Как это сделать, виднее самому разработчику, для начинающих же программистов можно посоветовать обращать внимание на условия вложенных циклов, чтобы избежать ненужных повторений.

Кроме того, всюду можно использовать массу мелких приемов. Например, для большинства задач, где не нужна очень высокая точность вычислений (особенно при округлении результатов), для констант, переменных и результатов выражений можно использовать тип float вместо double. В Java константы типа float заканчиваются символом F, а перед выражением достаточно поставить имя типа в скобках:

Alpha = (float) (Math.random() * 3.14F);

Для программистов, не использовавших ранее Java либо C/C++, рекомендуется привыкать использовать операторы, не встречающиеся в Pascal'e и других языках, такие, как "++", "-", "+=", "-=" и др. Они тоже быстрее выполняются программой.

Кроме того, используйте переменные, объявленные как свойства класса, не только для хранения значений, а для расчетов везде, где только можно, используйте частные переменные (private), объявленные внутри метода. Это правило заодно поможет избежать вероятных ошибок.

К сожалению, иногда оно нарушается даже в некоторых демонстрационных примерах, поставляемых вместе с JDK. Например, при поставке JDK версии 1.01 в исходниках известного апплета NervousText переменная, объявленная как свойство класса, использовалась исключительно как счетчик цикла в методах. В более поздних версиях эта оплошность была исправлена.

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

Новые средства разработки (Microsoft J++, Java Builder...) позволяют упростить некоторые этапы разработки проекта, но, на мой взгляд, к их применению надо подходить осторожно. Дело в том, что в первую очередь они позволяют визуально спроектировать интерфейс программы, однако используют при этом собственные объекты. Убедиться в этом можно, заглянув в заголовки исходных текстов, генерируемых этими пакетами, где описываются импортируемые классы (каждый из которых тоже импортирует что-то нестандартное). Даже для простейшей программы с несколькими кнопками и полями ввода дополнительно придется импортировать около десятка классов.

Почему именно так - непонятно, ведь Java - чисто объектно-ориентированный язык, и в стандартном наборе достаточно классов, реализующих всевозможные элементы управления с помощью ООП.

Стандартные классы Java поставляются вместе с виртуальной Java-машиной и поэтому при вызове не требуют предварительной загрузки через Сеть.

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

Таким образом, для разработки небольших программ вполне достаточно JDK (Java Development Kit) и ручного кодирования, иначе увеличенный объем приложения потребует неоправданных временных задержек, что может отрицательно сказаться на количестве клиентов Вашей службы.

Для корпоративных сетей, использующих выделенные каналы либо кабельные соединения, эта проблема стоит менее остро, поэтому наибольшее применение Java вкупе с вышеупомянутыми средствами разработки найдет именно там.

Если же проект сложный и автоматического проектирования (и, соответственно, импортирования нескольких десятков объектов) не избежать, то применяется известный метод - архивирование. Дело не в том, что файлы объектов *.class хорошо "жмутся" - в объеме разницы почти никакой, просто при пересылке браузер каждый раз открывает новое соединение, посылает на сервер информацию об имени файла и ждет ответа. Поэтому через модемное соединение гораздо быстрее скачать один большой файл (имеется в виду 30-40 Кб:-), чем двадцать-тридцать маленьких такого же суммарного объема. Java-машина при исполнении программы сама распакует нужные классы из архива прямо в оперативную память, надо лишь в разделе импорта указать путь к классу в архиве. Например,

import myclasses.zip/first.class

Можно использовать не только всем известный WinZip, но и другие архиваторы, пришедшие из мира Unix. Соглашения Unix также можно использовать для указания пути к файлам внутри архива, указания URL и т.д. Так что, изучение Java приоткроет Ваши Окна для освоения нового мира.

Желаю успеха.

Виктор Маковчик


Компьютерная газета. Статья была опубликована в номере 41 за 1999 год в рубрике программирование :: разное

©1997-2024 Компьютерная газета