Сэр Серж aka Sir Serge (Сергей Лебедев) - official site
Статьи и заметкиРасчетыО сайте

Халява, сэр.
Бесплатные средства кроссплатформенной разработки.

Holywar-like исследование, высосанное из эманаций эфира, глядючи в потолок.

Для кого это?

Для деятелей, собравшихся ваять проги так, чтобы они работали всюду — от венды до этих всяких линуксов и BSD – от free до corporate, но не видящих себе направления, потому что вдолбленый с детства Фортран (или что-то подобное ему) - рулит.

Для деятелей, которые сначала самостоятельно собирались сделать то, что описывается в одном абзаце выше, но им «чего-то слишком лениво».

Для профессионалов, которые от нечего делать хотят «почесать мозг». Для ассов (от омериканского ass) программирования, тех кто легко и непринужденно может нацарапать «HelloWorld» на любом языке программирования — от ассемблера до бейсика, от форта до модулы-2, и которым написать что-либо более сложное — влом, ибо от этого пострадает ширина охвата.

Бойтесь, ибо тема священна!

Предупреждение: изложенный ниже материал страдает ненаучным подходом к изложению, отсутствием диссертативности, ссылок на корифеев программостроения и теоретизаторов с учёными степенями, а также сильно отдает личным imho автора. Который, да! - туп, беспросветно ленив, бездарен, маниакален и безответственен.

Кроссплатформенность автора интересует в плане работы создаваемой самостоятельно программы под Linux и Windows, аппаратная платформа — i386/i586, 32 бита. Все остальные ОС автора на данный момент не обеспокаивают.

Из средств кроссплатформенного программирования автора интересует только то, что достается бесплатно. Поэтому нефиг пенять на то, что масса продаваемых за килобаксы сред осталась за рамками обзора.

За все годы существования программирования мечта «написать один раз — использовать сотню» была среди программистов навязчивой идеей. От нее произошли все библиотеки языков программирования, наборы пакетов, универсальные среды разработки, кросс-компиляторы и остальное.

Если ты, о читатель, не можешь понять, а зачем программа должна существовать на чем-нибудь, кроме Единственной Операционной системы — а именно Windows (а под Windows правильный пацан пишет на Delphi и мечтает о С++, ибо С++ для профессионалов, и это круто), убей себя об стену. После, стекая со стены, прочти далее: ибо отчасти ты прав.

Постулат к абзацу выше единственный:

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

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

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

(С) Крис Касперски

Итак, первые парочки:

C/C++ в «чистом» виде: gcc/g++ и MinGW

Собственно, когда-то задумывалось так, что язык Си является «стандартным» и «полностью переносимым». На деле, в зависимости от сред исполнения и операционных систем, в зависимости от реализации самого компилятора, программы на С и C++ при портировании требуют разного рода адаптации; причем, если для работы программы используется функционал операционной системы, какого-нибудь GUI, по-разному реализованного в разных средах, то в иных случаях проще программу переписать заново, чем адаптировать. Наиболее сложна адаптация программ, работающих с большим объемом данных сложной структуры и предназначенных для работы под 16-битной платформой. Те юные программисты, которые с этим всем никогда не сталкивались, даже представить себе не могут, как ловко изощрялись их предшественники для организации блоков памяти, превышающих 64к, особенно на машинах с весьма ограниченным объёмом оперативной памяти...

Linux в качестве базового и стандартного компилятора С и С++ предлагает gcc/g++; Поскольку это — основной инструмент разработки, он в достаточной степени вылизан, чтобы считаться стабильным и надёжным. С другой стороны, на платформе Windows предлагается порт gcc, именуемый MinGW. А вот с этим наследником всё не так просто. Во-первых, портируемые версии отстают на целое поколение. Во-вторых в MinGW реализованы не все стандартные для сред разработки Linux библиотеки. В третьих, сам runtime этих пакетов и поведение, как компилятора, так и исполняемых программ, различны; и то, что безукоризненно исполнялось под Linux, может приводить к довольно странным и труднолокализуемым ошибкам при переносе в Windows. Например, следующий сегмент кода вполне благополучно сработает под Gcc 4.1, и выведет черт знает что вместо значения второго аргумента printf в MinGW:

int main(int argc, char **argv)
{
   long long a=123456789;
   printf ("a=%Ld a=%Ld",a,a);
   return 0;
}

Ошибка, вероятно в том, как написана логика подсчета смещения аргумента в printf... Очень подозреваю, что адрес второго аргумента берется не средствами компилятора, а путем вычислений по спецификатору формата. Кстати, классический баг ранних версий библиотек gcc. Чтобы работало, всего-то достаточно выводить в одном printf по одной переменной такого типа, и она должна быть последней в списке. Ага, и подобного рода несовместимостей по форматам printf/scanf огромное количество, что сильно препятствует портированию. Например, тот же спецификатор %Ld в scanf версии MinGW оказывается неприменим к вводу данных long long, нужно использовать %I64d... Большие проблемы с вводом и выводом по scanf/printf данных long double.

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

Стандартным компилятором C++ для Windows является Visual C++. Казалось бы, столь далек он от линуксового gcc, но на самом деле программы, использующие исключительно стандартные библиотеки С/C++, довольно просто могут быть откомпилированы и с его помощью; следует просто сознавать, что проект придется создавать заново по исходным файлам, ибо похоже, средства make майкрософтовцы похоронили к версии Visual Studio 2008... И, все комментарии на национальных языках и строки, выводящиеся непосредственно из тела программы, подлежат обструкции, ибо Visual C++ 2008 работает преимущественно с исходными текстами в Unicode. Однако, остается разным поведение откомпилированной программы; по-разному инициализируются переменные в момент создания; те неаккуратные программисты, что использовали переменные без явного присвоения им значений до использования, могут открыть для себя много нового и необычного.

Более ранние версии Visual С++ не упоминаются и не рассматриваются по одной простой причине: в декабре 2009 года купить Visual Studio более ранней версии не представляется возможным; прав на использование более ранних версий покупка Visual Studio 2008 не дает; любителей стырить - отсылаю к части 2-й статьи 146 УК и части IV ГК РФ.

Вы спросите, зачем попал сюда Visual C++, изделие платное, и я отвечу, что есть версия express, которая может быть благополучно и бесплатно скачана с сайта Microsoft, и которую Microsotf разрешает использовать для разработок в коммерческих целях, ставя обязательным условием передачу исходного кода проекта заказчику вместе с двоичным кодом созданной программы. А как вы думали... За все нужно расплачиваться. Ввиду того, что Visual Studio 2008 Express нацелена только на создание программ под .NET, а это совсем другой подход и другая методика разработки, из Экспресса, например, безжалостно вымарана библиотека MFC и все библиотеки шаблонов ATL.

Практическим недостатком библиотек Visual C++ можно отметить редкостно тормозную реализацию классов поточного ввода/вывода стандартных библиотек C++. Что из этого следует: нефиг применять стандартные потоки C++ вообще; благо они популярностью среди программистов не пользуются.

Теперь о литературной поддержке языков. Увы, среди того, что предлагают книжные магазины, очень много учебников, посвященных непосредственно языку C++, но полностью отсутствуют книги, описывающую стандартную библиотеку компилятора, тем более вопросы того, как то или иное полагается делать в linux. Полагаться на MSDN в этом вопросе я бы не стал, поскольку Microsoft в некоторых вещах существенно отходит от базовых стандартов. Линуксовая справочная система Man ориентирует пользователя на использование только Cи, полностью умалчивая о том, что в библиотеках C++ линуксового исполнения есть адекватная поддержка, например, типа string, представляющего собой вполне хорошо работающие строки, вместо байтовых массивов, функции вызова которых, кстати, компилятор visual C++ радостно помечает комментариями «deprecated» и «угроза безопасности».

Среды исполнения.

Для windows, естественно, идеальна Visual Studio.

Впрочем, весьма неплоха и удобна NetBeans IDE, где с версии 6.5 поддержка проектов C/C++ значительно улучшена; в том числе в самой IDE прекрасно отслеживаются точки останова и локальные переменные (работаем с MinGW и отладчиком GDB). Кто сталкивался с GDB непосредственно, поймет, насколько это удобнее.

Интерфейсная библиотека QT

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

Своеобразные черты:

  • работает только через промежуточный компилятор, переводящий «нечитаемые» фрагменты кода в подходящий для компилятора C++ вид.
  • собственный make, из-за предыдущего пункта;
  • Собственные строки — только unicode utf-8... Внешние... Вот в этом-то при тестировании у меня возникла проблема. Проявилась она под linux, в котором utf-8 является системной локалью. Здесь, при использовании кириллицы, программа на QT, которая под windows работала великолепно, начала косячить самым непредсказуемым образом. В частности, при применении кириллических букв совместно с латиницей при выводе одной функцией нарушалось позиционирование и кернинг; кириллица была неправильно преобразована в unicode, и неправильно выведена на экран. Скорее всего, я что-то всё таки упустил из виду, но о таких особенностях национальной политики учебник, по которому программировался пример, старательно умолчал, как обычно.
  • Наличие двух лицензий — LGPL и коммерческой. Причем, если взглянуть на стоимость коммерческой лицензии, то при программировании под Windows например возникает вполне здравая мысль: «а зачем это нужно?»

    Казалось бы, все прекрасно и великолепно... Но, в связи с полной собственностью над trolltech (QT software) финской фирмы Nokia, вполне возможна ситуация, когда эта библиотека превратится в основное средство разработки программ для мобильных устройств, и эта ветвь пойдет в другом направлении, чем то, что останется для «нормальных» компьютеров.

    Delphi/C++Builder и Kylix

    Малыш, брось каку! Перечисленное в заголовке этом бесперспективно и подлежит забвению! Безоговорочно! Borland (Codegear, купленная какой-то мексиканской компанией, в нынешней реинкарнации) более не имеет средств кроссплатформенной разработки для языков C++ и Object Pascal.

    Проект Kylix, почивший в бозе после реализации версии 3.0, можно считать крайне неудачной попыткой этой фирмы создать среду разработчика под Linux. Нормально работала она только под RedHat и аналогичными дистрибутивами версий 6.0 и 6.1, во всех близкорасположенных более поздних выявляются подвисания при вызове окон открытия файлов, как для самой среды программирования, так и для программ, разработанных с ее помощью. CBuilder линуксовой версии вообще крайне неудачен и капризен, к тому же генерирует исполняемые файлы грандиозных размеров. Компилятор паскаля, впрочем, нареканий не вызывает. Но только именно компилятор, а не библиотеки визуального интерфейса и не среда программирования. Добавьте ко всему прочему увесистую стоимость пакета, невозможность его легального приобретения, и подумайте, зачем оно вам нужно.

    В некоторых околопрограммистских конференциях встречаются высказывания по поводу того, что Kylix – это бесплатная среда программирования. Никаких фактов, подтверждающих эту теорию, я никогда не встречал. Уши у волшебного кролика, вероятно, растут из того факта, что Kylix «как бы бесплатно» прилагался к Enterprise – версиям поставок Delphi Suite 6.0. Учитывая общую стоимость пакета, «бесплатность» была весьма умозрительной.

    FreePascal и Lazarus

    Не вдаваясь в историю возникновения и времена, можно сказать следующее: из всех «нормальных», то есть классических типизированных языков программирования, реализация FreePascal наиболее портабельна. Ибо, существует для всех распространенных платформ и не требует переделки программ при портировании почти абсолютно, за исключением, естественно, случаев прямого обращения к функциям операционной системы или внешним программам ОС, а также внешнего вида окон, связанного с разной метрикой шрифтов на разных операционных системах и оконных менеджерах. Недостатком для русскоязычного разработчика в самой ide FreePascal под linux является полная неподдерживаемость кириллицы, а так все прелестно — вплоть до полной поддержки невизуальных компонент библиотек delphi и даже функций модуля Graph, имитирующего подход к графике Turbo Pascal. Проблемы — несколько неадекватная реакция отладчика на просмотр данных в остановленной программе и невозможность выставления точек останова «по условиям». Проблемы с невозможностью просмотра значений переменных, являющихся членами классов, массивов объектов, если текущая трассируемая строка не относится к функции-члену этого класса. Проблемы с просмотром содержимого строк, куда попали символы, не являющиеся стандартной латиницей — они будут представлены кодом символа через знак «#».

    Lazarus – попытка имитировать delphi средствами FreePascal. Среда программирования практически полностью повторяет аналог, в поздних версиях предусмотрено преобразование проектов Delphi в Lazarus.

    Начиная с версии 0.9.26 — полная поддержка строк Unicode, при этом unicode взят в кодировке utf-8. Недостатки — неполноценный интерфейс с отладчиком, громадный объем исполняемого файла, связанный с невозможностью оптимизации классов, избыточно содержащих виртуальные методы, странное поведение системы в некоторых случаях. До сих пор в линуксовой реализации нет возможности стандартными средствами вывести русскоязычный текст на принтер.

    Отладчик Lazarus к версии 0.9.28 (конец 2009-го года) приобрел возможность отображать кириллицу в строках... Являющихся строками, входящими в состав констант... За что, конечно же, огромный респект разработчикам; однако, сама работа со строками в кодировке unicode все равно остаётся изрядным извращением, причем никак не документированным...

    Более или менее внятное описание доступно в lazarus wiki — относится только к тому, как правильно работать с именами файлов, чтобы они правильно воспринимались операционными системами с локалью, отличающейся от utf-8. Причем, все функции преобразования utf-8 в системную кодировку, помещены в модуле FileUtils, и это говорит само за себя.

    Следует отметить, что Lazarus разрабатывается, похоже, в первую очередь для Windows, и лишь далее адаптируется под остальные платформы; поэтому возможности линуксовой версии и поведение окон на экране благодаря другой модели обработки событий, сильно отличаются в худшую сторону, но в целом среду можно назвать вполне успешной... для радикальных энтузиастов.

    Литература: отсутствует и вряд ли планируется. Возможно использование книжек про Delphi, при этом стоит понимать, что совпадения в иерархии классов и их реализации неполные. По невизуальным компонентам и стандартным библиотекам fpc вместе с системой программирования поставляется вполне приличный мануал в виде файлов pdf, на английском языке. Сообщество в интернет по этой среде программирования крайне ограничено и разрознено. Географически, зона интереса к fpc/lazarus – в основном Германия и Россия.

    Среда разработки — собственно, Lazarus IDE. Нормальной онлайновой справочной системы нет. Отладчик не может показать переменные классов вне зоны прямой видимости того места, где стоит курсор текущей строки. Невозможно просмотреть в human-readable виде содержимое строк, содержащее кириллицу.

    Пикантность ситуации состоит в том, что начиная с версии 0.9.26 вся внутренняя обработка строк в оконной подсистеме производится исключительно в UTF-8, в то время как файлы читаются без учета локали вообще; а признак «юникодности» файла (кодированный префикс) не воспринимается функциями типа readln. Функции конвертации есть, но конечно же, они не документированы в основной справочной системе. Впрочем, кто ищет — тот найдет. Да, еще сюрприз! - Если строка содержит хотя бы одну ошибку в кодировке, препятствующую преобразованию в utf-8 или из utf-8, то результатом преобразования будет... пустая строка.

    Более того, отладчик не в состоянии отобразить более элементарные вещи. Невозможно:

  • отобразить элемент массива; даже если это массив из самых обычных чисел типа, например, double; не говоря уж о массиве объектов;
  • Объект отображается лишь целиком, со всеми полями. Если полем объекта является другой объект... То его отобразить уже не удаётся. То есть, посмотреть значение какого-либо отдельного поля объекта — весьма проблематично.
  • Строки, содержащие символы кириллицы или utf-8, отображаются в виде, похожем на следующее: «#234#233#234#232#20this»
  • В поле просмотра значений переменных и выражений невозможно получить результаты выполнения любой функции, как собственной, так и входящей в стандартные библиотеки; delphi уже на уровне версии 3 умел это делать.

    perl

    Интерпретируемая среда исполнения. Считается стандартной для всех Unix. Как ответственный элемент системы, вылизана и оптимизирована разработчиками полностью. Огромные репозитарии библиотек «на все случаи жизни». Существуют реализации интерфейса для perl с QT и c некоторыми другими интерфейсными библиотеками.

    Сам язык программирования благодаря особенностям синтаксиса дает возможность создавать наиболее короткий исходный текст по сравнению со всем, перечисленным здесь; особенно верно это для программ, связанных с обработкой строк и строковых массивов. Опять же, благодаря своеобразному синтаксису и ориентированности на regexp-выражения, perl настоятельно способствует порождению трудно воспринимаемых участков кода и так называемого «пендосско-индусского» стиля кодирования. Imho, программист, полностью проникшийся духом анархии perl, с большими затруднениями сможет адаптироваться к другим языкам разработки, особенно к языкам со строгой типизацией. Модель объектно-ориентированного программирования в реализации perl является имитацией таковой на уровне файловых модулей и вручную прописываемой виртуализации; довольно сложна для понимания и не способствует активному применению классов, наследования и пр.

    Порт под Windows – ActivePerl. Бесплатен.

    Совместимость между ОС: полная.

    Среды программирования: обычный текстовый редактор. :) Всё остальное — обычно платное. Поддежка Unicode до версии 5.8 в ядре языка полностью отсутствовала. К версии 5.10 все встроенные функции приобрели возможность работать со строками unicode, для чего таковые строки должны быть определённым образом «помечены» (возведён флаг unicode). Соответственно, при использовании данных смешанных форматов провоцируются различные непонятки; кроме того, не все ясно с сегментированием строк, индексацией символов и знаменитыми регулярными выражениями perl; То есть: поддержка unicode на сегодняшний день — в виде плохо скрываемых костылей и заплаток.

    Проблемные области для самого языка и его стандартных библиотек: рисование векторной графики; отображение растра. Средств не предусмотрено никаких. Не вдаваясь в глубину, автор предполагает, что данные аспекты в perl вообще не развиваются и не будут развиваться по одной простой причине: существуют средства «стыковки» модулей perl с подпрограммами и dll, написанными на C. Видимо, через эти возможности разработчики программ, которым необходима сложная графика, и действуют. В виду особенностей хранения информации в переменных perl, он очень слаб с точки зрения вычислительных возможностей; точнее говоря, с точки зрения производительности числовых вычислений.

    Появление в perl unicode привело к довольно забавным результатам: интерфейсная библиотека Tk, которая во всех учебниках описывается как «стандарт де-факто» для создания графического интерфейса программ на perl, исчезла из версии 5.10 ActivePerl; В линуксовых поставках она имеет место быть, но... с unicode не работает вообще и никак.

    php

    Относительно недавно появившийся язык WEB-программирования, перенасыщенный с избытком функциями самого разного назначения; полностью поддерживает объектно-ориентированное программирование, но не настаивает на его применении; полностью поддерживает unicode на уровне функций, хотя, конечно же, с «костылями»; из-за основной специфики применения — некоторые ограничения при создании программ, выполняющихся автономно. Отсутствуют стандартные средства работы с графическим интерфейсом. Привязан к глобальным конфигурационным файлам и html-оформлению.

    Менеджер памяти php, похоже, не рассчитан на работу с большими объемами данных и способен обеспечить непредсказуемые и нестабильные результаты при занятии массивами данных памяти более 150-200 мегабайт.

    Отсутствует типизация переменных и обеспечивается автоматическое преобразование строковых и числовых данных;

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

    Visual C# и Mono

    Продвигая свою среду исполнения .NET framework, Microsoft сделала C# ее основным языком разработки. Из всей языковой коллекции Visual Studio, С# наиболее продуман, и среда программирования сделана так, что разработка стала действительно приятным явлением. Глядя на это, группа сначала независимых разработчиков, а затем — под крылышком Novell, сделала open source порт .net framework и наименовала этот проект «Mono”. Оптимисты говорят, что это вполне полноценная система, заменяющая MS .NET и позволяющая в том числе исполнять программы, откомпилированные Visual Studio. Однако, тeкущая реализация — 2.0 у Mono, соответствует .NET версии между 1.2 и 2.0, в то время как текущая версия .net – 3.5; Среда разработки Monodevelop так и не вышла на стадию полноценного релиза; Ввиду объективных причин всегда будет отставание от прототипа и разница в реализации деталей; тем не менее, энтузиасты — добро пожаловать.

    Совместимость: частичная

    Литература: По Mono, как таковой, отсутствует вообще.

    Отличия от Microsoft-версии: вместо библиотек Windows Forms используются библиотеки интерфейса C# GTK2. Как выразился один из популяризаторов, программировать для gtk не столь сложно, сколь невероятно занудно. Великолепная и меткая характеристика.

    Интерактивный редактор форм для gtk, входящий в monodevelop, можно охарактеризовать полной непредсказуемостью и склонностью к самопроизвольным зависаниям; к тому же, в отличие от среды visual studio, он неспособен учитывать изменения в исходных текстах программы и работает строго односторонне — от графического интерфейса в сторону генерации текста сопровождения для компонент, используемых в проектируемом интерфейсе — что необходимо учитывать всякий раз, если не хотите, чтобы исправленные вами тексты были этим редактором повреждены.

    Отладчика в MonoDevelop нет. Точнее, он все-таки есть, но по умолчанию — выключен. Включить возможно только путем полной пересборки monodevelop с указанием соответствующих опций. Но и после этого гарантии работоспособности отладчика отсутствуют. Может работать, а может и не работать. Текстовый отладчик C#, как утверждается, работает вполне корректно. Ввиду того, что основной упор делается на WEB-функции .NET, то «кроссплатформенность» выражена фактически только для программ, не имеющих визуального интерфейса.

    JAVA

    Предшественник и прототип основных идей C#. Несмотря на вполне определенное противостояние этих программных платформ, общего чрезвычайно много. В том числе, разработчики библиотек C#, видимо, ориентировались в первую очередь на иерархическую модель объектов стандартных библиотек Java при создании своих структур, что делает программы на java вполне корректно и легко переводимыми на C#. Но не наоборот.

    По сравнению с C# в java отсутствует:

  • возможность изменения для основной программы параметров, передаваемых в функцию (в JAVA нет передачи параметров по ссылке, всё передается исключительно «по значению». Собственно, и объекты передаются «по значению», но значение переменной экземпляра объекта — это адрес, а потому содержимое полей объекта может подпрограммой изменяться)
  • перегрузка (переопределение) операций
  • изменение размерности уже определенных массивов в процессе исполнения
  • использование строк и перечислений в переменной выбора оператора switch … case
  • «свойства» класса, то есть параметры, внешне выглядящие как переменные, но на самом деле представляющие из себя код, отрабатываемый функциями get при чтении и set при записи значения; в частности, из-за этого отсутствует возможность представить какую либо структуру данных класса в виде индексированного массива, если эта структура массивом как таковым не является.
  • данные типа «беззнаковое целое»
  • оператор goto

    По сравнению и с C#, и с другими языками программирования, для строковой функции выбора сегмента substring принято очень своеобразное решение — сегмент выбираемой строки указывается не индексом первого символа и длиной, как практически везде, а индексом первого символа и индексом последнего символа в сегменте. Ситуация сия, хоть и не является смертельной, но способна порождать многочисленные ошибки при ручной адаптации текстов других языков, особенно близких по синтаксису, под java.

    Unicode в java поддерживается во вполне приличном (для обработки русского языка) виде; исключение составляют «костыли», используемые при необходимости обработки строк, символы которых не могут быть представлены в 16 разрядном виде — в этом случае в работу должны быть включены специализированные функции обработки кодовых точек и коррекция индексации с их использованием. «Префиксы» файлов unicode utf-8, впрочем, должны обрабатываться вручную.

    Java – один из немногих языков программирования, в стандартную поставку которого включены библиотеки обработки чисел с произвольной точностью; возможно, это основное, из-за чего java применяется в качестве стандартного инструмента написания всех расширений для таких монструозных банковских систем, как SAP.

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

    Пользователю, конечно, надо для этого инсталлировать виртуальную машину — но результат того стоит.

    Итак, из всех кроссплатформенных решений у java — серьезные преимущества в следующем:

  • огромное количество литературы и сообществ в интернете; найти адекватную книжку достаточно просто, в том числе и в книжных магазинах.
  • java давно уже стала стандартной программной платформой; поэтому интерфейсы ко всем известным базам данных и многим специализированным средам для нее обеспечены.
  • для java есть несколько превосходных ide программирования; полностью бесплатных и — тем не менее — действительно превосходных. В частности, NetBeans. Отличная среда программирования с великолепнейшим отладчиком.
  • поскольку unicode является стандартным для java, то снимается целый комплекс «финтов» с этим видом строк, характеризующий некоторые языки и библиотеки.

    Какие же недостатки?

    Собственно, серьезных недостатков — два:

  • Крайняя медлительность исполнения при работе с графическими функциями и математикой с плавающей точкой;
  • Чрезмерное потребление памяти программами java при их исполнении.

    Впрочем, быстродействие — это в первую очередь правильная организация алгоритмов, а отнюдь не достоинства самих компиляторов и исполняющих сред. А вот прозрачность исходного кода, сам язык, мало способствующий появлению нечитаемых фрагментов, и принудительная объектно-ориентированность, позволяет при наличии определенного навыка собирать и модифицировать готовые проекты очень быстро. Причем, очень большие проекты. Что касается потребления памяти.

    Для примера — некая программа, в основном работающая со строковым контентом. Считывает в память здоровенный лог сеансов АТС (при считывании парсит параметры в объекты), ну и далее при обработке этого массива занимается различными выборками, суммированием и преобразованием отдельных полей. Данные одни и те же. Была последовательно переписана на freepascal/lazarus – MS Visual C# 2088 – java (1.5.16).

    Результаты использования памяти процессом (при полностью загруженных данных) следующие:

    • freepascal/lazarus - около 25 мегабайт;
    • Visual C# - около 72 мегабайт;
    • java - 250 – 260 мегабайт.

    Повторяю — данные те же самые. Алгоритмика (в том числе и иерархия классов и их внутреннее строение) также радикальных изменений не претерпела.

    Ну и, соответственно, быстродействие. Если программы на lazarus и Visual C# по быстродействию отличались несущественно, то программа на java работала в 3-4 раза медленнее первого варианта.

    Можно задать вопрос — а почему было все-таки затеяно портирование первоначальной программы на freepascal, которая так здорово и экономично работала? А вот почему: не очень часто, но и не настолько редко, чтобы можно было говорить о том, что ситуация не повторяется, эта программа приводила операционную систему в какое-то странное состояние, при котором как бы все работало, но вот категорически не запускались программы, написанные на Lazarus и freepascal – в том числе сама ide lazarus, а также программы, имеющие явное про-борландовское происхождение — например, Total Commander. И так - до полной перезагрузки операционной системы. Что изрядно бесило, а порою создавало неприемлемые ситуации. Из-за чего это происходило, выявить так и не удалось, но я склоняюсь к мнению, что связано это своеобразное поведение с какими-то ошибками инициализации и освобождения графического контекста в самих библиотеках lcl lazarus.

    Поскольку у меня, как оказалось, это не единственная программа на lazarus, приводящая к такому эффекту.

    Так, что же еще стоит отметить относительно связки lazarus vs Visual C# vs java? Работа с файлами растровой графики (считывание, преобразование, вывод изображения, вывод масштабированного изображения):

    lazarus. Оценка по пятибалльной шкале — 3. Стандартный компонент TPicture не умеет нормально читать очень многие подформаты jpeg, не говоря уже о графике других форматов. То есть, вполне благополучно работавший viewer растровой графики на delphi версии например 7, преобразовать в проект lazarus не удастся. Нужно искать нестандартные библиотеки обработки jpeg или писать декодеры самостоятельно. Imho, работает так же, как и стандартная библиотека обработки jpeg из gtk+, а ограничения скорее всего патентные.

    java. Работа с графикой несколько неоднозначна. Стандартными средствами swing способна показать подавляющее большинство jpeg и других форматов с одним «но». Виртуальная машина должна быть Sun java. При попытке запустить под, скажем, свободной версией виртуальной машины java, которой принято комплектовать linux-дистрибутивы, сыпятся exception и не отображаются файлы примерно те же, что не может отображать lazarus. Ну и также, очень медленно происходит масштабирование изображений. Еще замечен следующий глюк: после вывода изображения gif, содержащего анимацию, начинают смаргивать все элементы окна.

    Visual C#. Вполне нормальная работа с графикой. Единственное, требуется аккуратно обрабатывать ситуации с файлами, которые не могут быть выведены на экран, до самой этой попытки вывода. Ибо, если таковая попытка произошла, то срывается функционирование всей исполняющей системы, и все графические элементы интерфейса необратимо превращаются в прямоугольники, перечеркнутые по диагонали. И так до завершения процесса.

    Работа с текстовыми файлами на чтение и запись.

    Visual C# - единственное, что неявно обрабатывает при чтении текстового файла сигнальный префикс utf 8 unicode. То есть, файл читается стандартными средствами, а в считанных строках этого префикса уже нет.

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

    Динамические массивы и коллекции.

    Фактически самая удобная объектная модель этих классов, наиболее близкая к практическому применению — у Visual C#. В том числе — очень удобно при написании программ общение с элементами таких массивов через индексы.

    Самая нерациональная модель — imho, у Delphi/FreePascal. К тому же, мало совместимая со всеми остальными библиотеками языков программирования. Ну так... Что взять с исторического прототипа, которому уже больше десятка лет...

    Остальное.

    А как же TCL/TK, а как же python??? А как же еще много чего, вкусного и иногда бесплатного?

    Да. Существуют. Автор до них на сегодня не добрался. Ибо для него на текущий момент нет ни малейших стимулов и необходимости изучения этих сред программирования. Возможно, они прекрасны. Пробуйте. :)

    В заключение, чего по мнению автора, делать не надо.

    Господа!

    Хороните, наконец массовое изучение Borland Pascal, Delphi и C++ Builder. Будущего у этих сред программирования нет.

    Отдавая должное своевременности их появления многие годы назад, отдавая должное тому, что когда-то эти среды программирования были едва ли не самыми удобными для программиста инструментами — (в основном, из-за великолепной справочной системы), к сожалению, можно констатировать, что их жизненный цикл подошел к концу. В первую очередь потому, что Microsoft наконец то напряглась и породила Visual Studio, по характеристикам превосходящую borland-like и стоящую для конечного потребителя ощутимо меньших денег.

    Сомневающиеся, да найдут и откроют книжку по академическому языку pascal и сравнят его с тем, во что мутировал Object Pascal фирмы Borland, а тем более во что мутировал Object Pascal в реализации freepascal... Осталось немногое — замена begin и end на «{}», “:=” на «=», “<>” на «!=» - и наконец то одинарных кавычек на двойные - и перед вами будет нечто очень похожее на C#. Или на C++. Хотя, последний также еще тот мутант. Плюс к этому — набор библиотек работы с динамическими массивами и коллекциями крайне архаичной архитектуры. Плюс к этому — чудовищные баги в реализации библиотек, присущие как оригиналу, так и последователям...

    Право же, не стоит...

    Сегодня все можно сделать проще и другими способами.

    Обратная сторона Луны.

    Смотрите, сколько прекрасных бесплатных инструментов для разработчика! - скажете вы. А в чем, собственно, подвох? Внимательно смотрим лицензии. Если это GPL для какой-нибудь runtime, прилинкованной к вашей программе,– то вы обязаны при распространении программы предоставлять пользователю ее исходный код. Если не предоставляете, или же если вам нужны расширенные функции, которых в community- версии просто нет — то вы обязаны купить коммерческую версию (той же qt). Взгляните на цену, пожалуйста. И на порядок использования.

    Express версии Visual Studio в некоторых редакциях также требовали передавать ваши коммерческие проекты, подготовленные с использованием этой среды программирования, только с предоставлением конечному пользователю исходного кода; В версии EULA на русскую VS Express 2008 SP2 такого требования уже нет. Есть и еще один нюанс: ни один из компиляторов, входящих в Visual Studio, кроме C++, не может в принципе создавать код, не являющийся бит-кодом виртуальной машины. А если вы хотите создать такой код на С++, то вы, соблюдая чистоту традиций, не должны пользоваться ничем тем, что выходит за рамки генерации «чистого» машинного кода. Да и надо сказать, описания функций библиотек управляемого кода для С++ настолько плохо воспринимаются (они длинные и изобилуют многочисленными подчёркиваниями), а использование именно этого языка в .net или даже в создании обычных приложений, не имеет в основном никаких преимуществ, так что стоит задуматься, надо ли с этим всем связываться, а уже тем более — надо ли лезть в дебри Microsoft Foundation Classes, которые доступны только владельцам коммерческих версий среды, да и архаичны настолько, что собственно Microsoft в своей деятельности давным давно избегает использования этой библиотеки.

    Чем же плох бит-код? В основном, тем, что он без особого напряжения декомпилируется во вполне подходящие для изучения логики программы инструкции, а некоторыми инструментами — и напрямую в исходный код того языка, на котором был написан проект. То же самое верно и для java, причем декомпиляторов для этой среды понаписано еще больше, и среди них периодически встречаются и полностью бесплатные, и вполне работоспособные. Так что, если очень хотите «спрятать» алгоритм работы вашей программы от любопытных — определитесь, чем и как это делать, заранее.

    Скорость работы.

    Исходная постановка задачи:

    Дано:

    Текстовый файл, содержащий строки переменной длины по 11 полей каждая; поля разделены символом табуляции; файл не содержит символов, выходящих за кодировку ASCII; Объём — 101 мегабайт (1594445 строк)

    Требуется:

    1. Прочитать весь файл в динамический массив в оперативной памяти. Засекаем время этой операции. То есть, открытие файла, чтение и размещение. В отчете это будет операция «Load».

    2. Пройти по считанному в память массиву строк; произвести разделение каждой строки на все возможные поля по указанному разделителю. Первое поле строки преобразовать в тип long (longint) и создать в памяти массив (в данном случае из 1594445 элементов типа long), который заполнить полученными значениями. В отчете это операция «Parse».

    3. По созданному в п.2 массиву пройти 1000 раз и произвести вычисления путем прямого перебора максимального и минимального элементов массива, а также его среднего значения. Чтобы было повнушительнее, каждое значение при сравнениях и присваивании делится на 10000; (проверяем быстродействие целочисленной арифметики). В отчете - это операция «long».

    4. По созданному в п.2. массиву пройти 100 раз и произвести суммирование исполнения результатов функции Acos(Sqrt(Abs(Sin(a) / Cos(a)))) / 0.833; где а — значение преобразованного в double элемента массива, деленное на 100000005.23; (проверяем быстродействие арифметики с плавающей точкой). В отчете — это операция «double»;

    5. Программы, на которых это действо будет производиться — под командную строку; усилия для локализации не применяются.



    Теперь, верхняя часть таблицы. То есть, исполняющая среда.

    1 — CPU AMD ML-28, 1533 MHz, одноядерный без HyperThreading, Windows XP 32 bit, RAM 2Gb; Ноутбук Compaq nx6125;

    2 – CPU Intel Atom 300, 1600 MHz, двухядерный с HyperThreading, Windows 7 HP, 64 bit, RAM 2Gb; m/b Intel DGCLF2, стандартный винчестер 3.5";

    3 — CPU Intel Atom 260, 1600 MHz, одноядерный с HyperThreading, Windows XP 32 bit, RAM 2Gb, Ноутбук Acer One, с HDD.

    4 – CPU AMD Athlon XP 2400+, 2000 MHz, одноядерный без HyperThreading, ASP Linux 14, RAM 2Gb. SUN JAVA 1.5.16, mono 2.1;

    5 – CPU AMD Athlon XP 2400+, 2000 MHz, одноядерный без HyperThreading, Windows Vista 32 bit, RAM 2 Gb

    Использованные компиляторы/библиотеки:

    • Sun JAVA 1.6.0_16 (в случае 64-битной версии ОС — 1.6.0_17, 64 битная)

    • perl 5.10 / ActivePerl 5.10 (на 64-битной ОС — 64-разрядная версия)

    • компилятор MinGW, актуальная версия на декабрь 2009 года

    • gcc от штатной поставки ASP Linux 14.0

    • FreePascal 2.5.1 (Комплект Lazarus CodeTyphon)

    • Visual Studio 2008





    ML-28
    Win XP 32x

    Atom 330
    Win 7 64x

    Atom 260
    Win XP 32x

    Athlon XP 2400+
    Linux 32x

    Athlon XP 2400+
    Win Vista 32x

    JAVA -Xms500M -Xmx1000M

    Load

    3

    4

    5

    7

    4

    Parse

    14

    13

    21

    13

    14

    Long

    137

    30

    175

    122

    110

    Double

    272

    420

    430

    239

    264

    C#

    Load

    14

    5

    5

    3

    6

    Parse

    5

    9

    7

    7

    5

    Long

    100

    100

    166

    138

    124

    Double

    52

    130

    110

    62

    49

    fpc

    Load

    3

    8

    4

    4

    8

    Parse

    33

    74

    68

    6

    33

    Long

    22

    41

    40

    22

    27

    Double

    122

    123

    124

    52

    57

    perl

    Load

    6

    15

    11

    6

    8

    Parse

    18

    29

    30

    14

    17

    Long

    2600

    4000

    4200

    3000

    2600

    Double

    760

    1660

    1390

    1120

    710

    C++ gcc/MinGW

    Load

    4

    6

    5

    2

    5

    Parse

    30

    49

    54

    14

    30

    Long

    21

    48

    48

    34

    23

    Double

    124

    238

    244

    53

    55

    C++ VS2008

    Load

    5

    19

    7

    -

    -

    Parse

    23

    144

    47

    -

    -

    Long

    11

    25

    26

    -

    -

    Double

    43

    118

    118

    -

    -

    Исходные тексты программ:


    JAVA:
    С#
    FreePascal:
    C++
    Perl:

    Примечания к текстам программ:

    Что касается исходных текстов, то, увы, пришлось пойти на поводу у некоторых допущений.

  • Поскольку у perl принципиально нет разделения на целые и вещественные числа и вся математика исчисляется в вещественном виде, да еще и постоянно конвертится из строк в числа, то вот и результаты - в катастрофической производительности математики. Да, еще пришлось двигать определения sub, не то функция по циклу так и норовила исполниться вместо предписанного количества раз - единожды. Ну и счетчик уменьшен, дабы реально не ждать часами результата.
  • В версии freePascal было чрезвычайно лениво писать функцию, которая бы парсила за один проход все поля строки; а приведенный аналог, вырезающий по одному полю, при проходе через все поля даёт чрезмерно завышенное значение по времени, за счет избыточности процедуры повторного прохода. Посему было чисто умозрительно выбрано, что выбирается из строки три поля, и это якобы эквивалентно по времени выборке остальных полей за один проход.
  • Функция Parse в версии C++ является вообще говоря некорректным кодом как с точки зрения переносимости, так и с точки как безопасности, так и правильности программирования; о чем, кстати матом орет исполняющая система visual c++, если программу слинковать с отладочными библиотеками. Данный код валится под gcc на linux, до тех пор, пока в коде, вызывающем эту функцию, не заремить delete на то, что она вернула. Ну, поскольку формально то что нужно, выполняется, то пусть так и будет.
  • В громадное недоумение поверг меня тот факт, что из основных библиотек free pascalя, в том числе в режиме delphi, оказывается, выброшена вся обратная тригонометрия и гиперболические функции... Мда. Я, конечно, понимаю, что лучше не иметь того, что может создать исключения в коде вообще, чем заставить код эти исключения корректно обрабатывать... Но... Зачем же делать худьшим то, что могло бы быть лучше хотя бы капельку, и что существенно увеличивает потенциальную область применения и удобства...

    Ну с... Результаты...

    Вполне логично, что между С++ и FreePascal, особенно между C++ в некоммерческой реализации, заметной разницы при работе с целыми числами не наблюдается. Плавающая арифметика же в MinGW на процессорах Atom что-то очень уж плохо сработала. На остальных - опять же нет разницы в производительности. Ну и самый быстрый код, извините, получается у коммерческого компилятора c++ visual studio 2008. Причем и на атомах тоже.

    perl, естественно, аутсайдер по вычислениям... Что и подозревалось.

    А вот java и c#, как мне кажется, дают довольно неоднозначные результаты. В частности, как вы видите, 64-битная java под 64-битной операционной системой измудрилась обогнать все и вся при операциях с числами long. Что говорит о том, что теоретически может существовать адаптированный под виртуальную машину java процессор, на котором она будет работать непревзойденно быстро. А так, на x86 - epic fail всего лишь на арифметике с плавающей точкой, все остальное - достаточно приемлемо по скорости. Ну и удивил меня почти не отстающий по производительности от "правильных компиляторов" C# при плавающей арифметике. Причем, как оказалось, и mono в этом отношении достаточно производителен. Код, правда, использовался тот, что был сгенерирован VS2008, собственный компилятор mono я не проверял.


    Всего комментариев: 3

    na OC: Windows XP   2010-01-08 21:11:15


    "Смотрите, сколько прекрасных бесплатных инструментов для разработчика! - скажете вы. А в чем, собственно, подвох? Внимательно смотрим лицензии. Если это GPL – то вы обязаны при распространении программы предоставлять пользователю ее исходный код."

    Стоит ли это понимать так, что если я использую NetBeans + Cygwin/MinGW gcc/g++, то я тоже должен показать исходники своего продукта, скомпилированного вышеперечисленным. Если да, то хотелось бы быть тыкнутым в то место лицензии (лицензий), которое поясняет этот пункт. Если нет, то хотелось бы отсутсвия расплывчатости фразы "Если это GPL – то вы обязаны ..."

    "Express версии Visual Studio, кстати, также требуют передавать ваши коммерческие проекты, подготовленные с использованием этой среды программирования, только с предоставлением конечному пользователю исходного кода;"

    На это опять хочется увидеть пруфлинк.


    Sir Serge OC: Vista   2010-01-09 11:01:42


    >> "Стоит ли это понимать так, что если я использую NetBeans + Cygwin/MinGW gcc/g++, то я тоже должен показать исходники своего продукта, скомпилированного вышеперечисленным."

    Нет, не стоит. RunTime MinGW, насколько я понимаю, public domain, то есть - общественное достояние. То есть, продукт деятельности можете распространять как угодно и под какой угодно лицензией, в том числе и с закрытым текстом. Но. Если в составе вашего продукта есть хотя бы один компонент (библиотека) под GPL, вам придется раскрыть по крайней мере код, взаимодействующий с этим компонентом, а если этот компонент вами модифицирован - предоставить исходники модифицированного компонента. Будете менять сам компилятор или его библиотеки - исходники, пожалуйста обществу.

    А вообще вот из GPL цитата:
    "if you distribute copies of such a program,
    whether gratis or for a fee, you must give the recipients
    all the rights that you have. You must make sure that they,
    too, receive or can get the source code."

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

    Что касается Express версий Visual Studio, данная формулировка, насколько помнится, присутствовала в первой версии выданного сообществу дистрибутива, когда VS была строго английской. В русской Eula на данный момент этой фразы нет.

    UPD: 2010/01/11 - текст по поводу лицензий подправлен.


    Andrey OC: Vista   2010-12-27 15:30:40


    Добрый день, поправьте пожалуйста "CodeTyphoon" на CodeTyphon. В дополнении хотелось бы заметить, что как FreePascal, так и Lazarus разрабатываются исключительно силами сообщества без денежных инъекций и это лучшая гарантия того, что он всегда будет свободным от проприетарщины инструментом, существующие проблемы активно дорабатываются, а сложности с отладчиком обусловлены тем, что используется GDB, который ну никак не предназначался для отладки приложений, собранных pascal-компиляторами. Что же касается больших размеров файлов - честно говоря, уже устали повторять разработчики на FPC, что это очень просто решается соответствующими флагами компилятора, причем указываемым из среды в свойствах проекта, плюс в версии 2.5.1 точно есть возможность выносить отладочную информацию в отдельный файл - для сравнения: бинарник собранный с оптимизацией -O3 в FPC меньше бинарника С++/Qt со статической линковкой.



    Текст опубликован: 2010-01-11

    Последние изменения текста: 2010-01-11


    Вы можете добавить свои комментарии.

    Комментарий появится на сайте только после того, как он будет проверен администрацией на запрещённую законодательством информацию.

    Для возможности внесения комментариев в браузере должна быть включена поддержка JavaScript. Реклама и ссылки на сайты, не относящиеся к делу, являются прямым основанием удаления комментария. Поля "E-mail" и "WWW" обязательными для заполнения не являются, поле E-Mail не публикуется. Если хотите просто что-то написать автору статьи, без публикации на сайте - воспользуйтесь специальной формой под пунктом меню "О сайте". Администрация оставляет за собой право публиковать или не публиковать адреса, введенные в поле www, а также при необходимости редактировать текст вашего сообщения. Ответы на ваши сообщения по введенному вами E-mail автоматически сайтом не высылаются. Теги PHPBB и HTML не действуют.


    Ещё тексты по этой теме:

    Отображение графики SVG, получаемой со скрипта на сайте (2019-04-29/2019-04-29)
    64-битный компилятор MinGW + NetBeans 8.2. Установка под Windows 10 x64 (2017-11-06/2017-11-06)
    Представление о времени в операционных системах и языках программирования (2016-05-11/2016-05-11)
    Использование строк UnicodeString и маркированных кодовой страницей AnsiString/RawByteString в приложениях Lazarus/LCL (2012-12-14/2012-12-14)
    Символы и строки в Unicode-версиях FreePascal (2012-07-19/2012-07-23)
    Национальный вопрос в C/C++ (2011-12-09/2011-12-09)
    Lazarus :: Resurrection :: прикладная кадаврология (2011-11-11/2011-11-11)
  • Copyright © 2003-2024 by Sir Serge