Удалить url в яндексе webmaster. Как удалить URL адреса из поисковой выдачи Google и Яндекс. Использование инструмента не по назначению

Язык программирования - это система обозначений, служащая для точного описания программ или алгоритмов для ЭВМ. Языки программирования являются искусственными языками. От естественных языков они отличаются ограниченным числом “слов” и очень строгими правилами записи команд (операторов). Поэтому при применении их по назначению они не допускают свободного толкования выражений, характерного для естественного языка.

Basic. Он был разработан в 1963 году профессорами Дартмутского колледжа Томасом Курцем и Джоном Кемени. Язык предназначался для обучения программированию и получил широкое распространение в виде различных диалектов, прежде всего как язык для домашних компьютеров. При проектировании языка использовались следующие восемь принципов: 1.Быть простым в использовании для начинающих 2.Быть языком программирования общего назначения 3.Предоставлять возможность расширения функциональности, доступную опытным программистам 4.Быть интерактивным 5.Предоставлять ясные сообщения об ошибках 6.Быстро работать на небольших программах 7.Не требовать понимания работы аппаратного обеспечения 8.Защищать пользователя от операционной системы. Язык был основан частично на Фортран II и частично на Алгол-60, с добавлениями, делающими его удобным для работы в режиме разделения времени и, позднее, обработки текста и матричной арифметики. Синтаксис языка напоминает Fortran, и многие элементы - явные заимствования из него. Язык задумывался для обучения, поэтому его конструкции максимально просты. Как и в других языках программирования, ключевые слова взяты из английского языка. Основных типов данных два: строки и числа. Объявление переменных не требует специальной секции (в отличие, например, от Паскаля). Объявление переменной - это первое её использование.

C Sharp - C# (произносится си шарп) - объектно-ориентированный язык программирования. Разработан в 1998-2001 годах группой инженеров под руководством Андерса Хейлсберга в компании Microsoft как язык разработки приложений для платформы Microsoft.NET Framework. C# относится к семье языков с C-подобным синтаксисом, из них его синтаксис наиболее близок к C++ и Java. Язык имеет статическую типизацию, поддерживает полиморфизм, перегрузку операторов (в том числе операторов явного и неявного приведения типа), делегаты, атрибуты, события, свойства, обобщённые типы и методы, итераторы, анонимные функции с поддержкой замыканий, LINQ, исключения, комментарии в формате XML. Переняв многое от своих предшественников - языков C++, Java, Delphi. С#, опираясь на практику их использования, исключает некоторые модели, зарекомендовавшие себя как проблематичные при разработке программных систем, например, C# не поддерживает множественное наследование классов (в отличие от C++).


Язык программирования C++ - компилируемый статически типизированный язык программирования общего назначения. Поддерживает разные парадигмы программирования, но, в сравнении с его предшественником - языком Си, - наибольшее внимание уделено поддержке объектно-ориентированного и обобщённого программирования. Название «Си++» происходит от Си, в котором унарный оператор ++ обозначает инкремент переменной.В 1990-х годах язык стал одним из наиболее широко применяемых языков программирования общего назначения. При создании Си++ стремились сохранить совместимость с языком Си. Большинство программ на Си будут исправно работать и с компилятором Си++. Си++ имеет синтаксис, основанный на синтаксисе Си.

Достоинства C++ - чрезвычайно мощный язык, содержащий средства создания эффективных программ практически любого назначения, от низкоуровневых утилит и драйверов до сложных программных комплексов самого различного назначения. В частности : Высокая совместимость с языком С, позволяющая использовать весь существующий С-код (код С может быть с минимальными переделками скомпилирован компилятором С++; библиотеки, написанные на С, обычно могут быть вызваны из С++ непосредственно без каких-либо дополнительных затрат, в том числе и на уровне функций обратного вызова, позволяя библиотекам, написанным на С, вызывать код, написанный на С++). Поддерживаются различные стили и технологии программирования, включая традиционное директивное программирование, ООП, обобщенное программирование, метапрограммирование (шаблоны, макросы). Имеется возможность работы на низком уровне с памятью, адресами, портами. Возможность создания обобщённых контейнеров и алгоритмов для разных типов данных, их специализация и вычисления на этапе компиляции, используя шаблоны. Кроссплатформенность. Доступны компиляторы для большого количества платформ, на языке C++ разрабатывают программы для самых различных платформ и систем. Эффективность. Язык спроектирован так, чтобы дать программисту максимальный контроль над всеми аспектами структуры и порядка исполнения программы. Недостатки Отчасти недостатки C++ унаследованы от языка-предка - Си, - и вызваны изначально заданным требованием возможно большей совместимости с Си. Это такие недостатки, как: Синтаксис, провоцирующий ошибки: Препроцессор, унаследованный от С, очень примитивен. Плохая поддержка модульности (по сути, в классическом Си модульность на уровне языка отсутствует, её обеспечение переложено на компоновщик). Подключение интерфейса внешнего модуля через препроцессорную вставку заголовочного файла (#include) серьёзно замедляет компиляцию при подключении большого количества модулей (потому что результирующий файл, который обрабатывается компилятором, оказывается очень велик).

Паскаль . Появившийся в 1972 году язык Паскаль был назван так в честь великого французского математика XVII века, изобретателя первой в мире арифметической машины Блеза Паскаля. Этот язык был создан швейцарским учёным, специалистом в области информатики Никлаусом Виртом как язык для обучения методам программирования. Паскаль – это язык программирования общего назначения. Особенностями языка являются строгая типизация и наличие средств структурного(процедурного) программирования. Паскаль был одним из первых таких языков. По мнению Н. Вирта, язык должен способствовать дисциплинированию программирования, поэтому, наряду со строгой типизацией, в Паскале сведены к минимуму возможные синтаксические неоднозначности, а сам синтаксис интуитивно понятен даже при первом знакомстве с языком. Язык Паскаль учит не только тому, как правильно написать программу, но и тому, как правильно разработать метод решения задачи, подобрать способы представления и организации данных, используемых в задаче. С 1983 года языкПаскаль введён в учебные курсы информатики средних школ США.

Язык программирования Delphi (Дельфи) - среда разработки, использует язык программирования Delphi (начиная с 7 версии язык в среде именуется Delphi, ранее - Object Pascal), разработанный фирмой Borland и изначально реализованный в её пакете Borland Delphi, от которого и получил в 2003 году своё нынешнее название. Object Pascal - по сути является наследником языка Pascal с объектно-ориентированными расширениями. Delphi обеспечивает визуальное проектирование пользовательского интерфейса, имеет развитый объектно-ориентированный язык Object Pascal (позже переименованный в Delphi) и уникальные по своей простоте и мощи средства доступа к базам данных. Язык Delphi по возможностям значительно превзошел язык Basic и даже в чем-то язык C++, но при этом он оказался весьма надежным и легким в изучении (особенно в сравнении с языком C++). В результате, среда Delphi позволила программистам легко создавать собственные компоненты и строить из них профессиональные программы.

Java - объектно-ориентированный язык программирования, разработанный компанией Sun Microsystems - 23 мая 1995 года. Программы на Java транслируются в байт-код, выполняемый виртуальной машиной Java (JVM) - программой, обрабатывающей байтовый код и передающей инструкции оборудованию как интерпретатор. Достоинство подобного способа выполнения программ - в полной независимости байт-кода от операционной системы и оборудования, что позволяет выполнять Java-приложения на любом устройстве, для которого существует соответствующая виртуальная машина. Другой важной особенностью технологии Java является гибкая система безопасности благодаря тому, что исполнение программы полностью контролируется виртуальной машиной. Любые операции, которые превышают установленные полномочия программы (например, попытка несанкционированного доступа к данным или соединения с другим компьютером) вызывают немедленное прерывание. Часто к недостаткам концепции виртуальной машины относят то, что исполнение байт-кода виртуальной машиной может снижать производительность программ и алгоритмов, реализованных на языке Java. В последнее время был внесен ряд усовершенствований, которые несколько увеличили скорость выполнения программ на Java: применение технологии трансляции байт-кода в машинный код непосредственно во время работы программы (JIT-технология) с возможностью сохранения версий класса в машинном коде, широкое использование платформенно-ориентированного кода (native-код) в стандартных библиотеках, аппаратные средства, обеспечивающие ускоренную обработку байт-кода (например, технология Jazelle, поддерживаемая некоторыми процессорами фирмы ARM).

Основные возможности: автоматическое управление памятью; расширенные возможности обработки исключительных ситуаций; богатый набор средств фильтрации ввода/вывода; набор стандартных коллекций, таких как массив, список, стек и т. п.; наличие простых средств создания сетевых приложений (в том числе с использованием протокола RMI); встроенные в язык средства создания многопоточных приложений; параллельное выполнение программ.

Таким образом, в наше время существует множество языков, и у каждого из них свои особенности.

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

Простота использования

Как определить, насколько легко новичку выучить язык программирования? За базис лучше всего брать школьный Pascal: возможности там были не великие, зато близость к английскому языку и отсутствие лишних действий на первых порах позволяют проникнуться к языку большой симпатией. То есть человек, не обладающий исключительными навыками в программировании, может или сразу, или после короткого ликбеза интерпретировать код начальной сложности. По такому критерию к сложным в данном случае можно отнести Assembler или C++.

Но есть и другой взгляд: брать за самый сложный язык тот, по которому вы сможете отыскать меньше всего литературы, в частности на русском языке. Как правило это недавно созданные экземпляры или практически не имеющие реального применения в современном мире. Но тут здесь возникает большая сложность градации: если условные Rust или C можно расставить по разным полюсам рейтинга без особых проблем, то как быть с давним спором Ruby и Python?

Прибыльность

Это то, на что обращают внимание молодые умы и посетители сайтов с онлайн-курсами. Ведь всегда есть вопросы: «если я изучу C, когда ко мне придёт миллион? А будет с Python быстрее?». Но дело в том, что оценка языка, как источника дохода, напрямую зависит от рыночной ситуации. То есть возможно язык Haskell и принесёт вам большой доход, но лишь в том случае, если вы найдёте соответствующую работу. А вот со знанием PHP вы сможете начать зарабатывать свой миллион раньше, правда потратите втрое больше чистого времени.

Было бы разумным ввести некую единицу оценки прибыльности исходя из соотношения зарплата/вакансия. Тогда, скорее всего, в лидерах бы оказались языки для мобильных платформ Android и iOS, т.е. Java и Swift. Однако в данном случае стоит вопрос необходимости и достаточности знания профильного языка: если безупречное владение тем же PHP может составлять 30% «must-have» требований, то вот Swift вряд ли потянет и на 10%. Да и является ли показателем качества языка количество вакансий? Может быть, всё в точности наоборот?

Быстродействие

Ещё один довольно спорный фактор, зависящий по сути от двух факторов - поставленной задачи и используемой машины, то есть абсолютно субъективных факторов. Нет, конечно, мы можем взять одну машину и устроить на ней сотни тестов разной сложности, чтобы выяснить, что C - это отличный язык программирования по быстродействию, а в самом низу списка будет Basic. Но градация скорости в середине вновь будет очень небольшой и брать её за показатель преимущества - нелепо.

Удобство

Субъективный параметр, который тем не менее, часто принимается за доказательство. Удобным язык может называться, если стандартные конструкции в нём записываются максимально коротко. Также удобным языком можно называть тот, где риск появления плавающей ошибки минимален. Удобный язык - этот тот, для работы с которым создано множество редакторов, плагинов, надстроек и пр. На самом деле любой основополагающий принцип языка можно выдать за удобство и оказаться правым. Так что такое удобство?

Область применения

Вот это первый аргумент в сегодняшнем списке, который можно посчитать, привести примеры и выявить победителя. Однако в каком случае данный спор выявит победителя? В каком случае количество бьёт качество? В споре двух мальчишек на уроке информатики? В реальной ситуации, когда человек подбирает себе инструмент для конкретной задачи или будущей работы, вопрос выбора языка с широким диапазоном применения обычно не стоит. Как правило, ситуация обратная: чем уже специализация, тем эффективнее применение языка. То есть знать несколько языков куда полезнее, чем один, но “широкоформатный”.

Функциональность

Функциональность и возможности - это как раз то, что можно почерпнуть из соответствующей таблички в Википедии . Сравнение полезное, достаточно полное и спорить с собеседником можно просто тыкая в соответствующую таблицу. Но вновь возвращаемся к эффективности такого сравнения: сподобят ли вас потенциально большие возможности взяться за изучение нового языка? Или это только отпугнёт?

А как вы считаете, можно ли сравнивать языки программирования? По каким ещё критериям?

Недавно очередной раз отработал со студентам 2-го курса 2-семестровую дисциплину «Алгоритмические языки». Обзорно рассмотрели несколько дюжин языков программирования. Один из студентов, Вадим Шукалюк, захотел получше с ними познакомиться, получить более четкое представление о каждом из них. Посоветовал ему провести небольшое исследование. Чем и увлёк. Предлагаю свой отчёт по проделанной за несколько месяцев вместе с ним работе.

У каждого языка программирования есть свои достоинства и недостатки. Одна из важнейших характеристик транслятора с любого языка — это скорость исполнения программ. Очень трудно или даже невозможно получить точную оценку такой скорости исполнения. Ресурс http://benchmarksgame.alioth.debian.org/ предлагает игровую форму для проверки такой скорости на разных задачах. Но число языков, представленных на этом ресурсе, довольно невелико. Предельную ёмкость стека, критическую величину для рекурсивных вычислений проверить проще, но она может меняться в разных версиях транслятора и быть зависимой от системных настроек.

Тестировались следующие трансляторы: си (gcc, clang, icc), ассемблер (x86, x86-64), ява (OpenJDK), паскаль (fpc), яваскрипт (Google Chrome, Mozilla Firefox), лисп (sbcl, clisp), эрланг, хаскель (ghc, hugs), дино, аук (gawk, mawk, busybox), луа, рубин, бейсик (gambas, libre office), питон-2, пи-эйч-пи, постскрипт (gs), пролог (swipl, gprolog), перл, метапост, Т E Х, тикль, бэш. Исследовались как собственно скорость исполнения нескольких небольших, но трудоёмких алгоритмов, так и:

  • качество оптимизации некоторых трансляторов;
  • особенности при работе с процессорами Intel и AMD;
  • предельное число рекурсивных вызовов (ёмкость стека).
В качестве первой задачи, на которой тестировались все трансляторы, выбран расчёт числа Фибоначчи двойной рекурсией согласно определению: числа с номерами 1 и 2 — это единицы, а последующие — это сумма двух предыдущих. Этот алгоритм имеет несколько привлекательных особенностей:
  1. Если время расчета n-го числа t, то (n+1)-го — t*φ, где φ — это золотое сечение равное (√5+1)/2;
  2. Само вычисляемое n-e число равно округлённой до ближайщего целого величине φ n /√5;
  3. Расчёт fib(n+1) требует n-й вложености вызовов.
Первая особенность позволяет за небольшое время протестировать трансляторы, скорости работы которых различаются в сотни тысяч раз. Вторая особенность позволяет быстро проверять правильность расчетов. Третья особенность теоретически позволяет исследовать ёмкость стека, но из-за того, что расчет при n > 50 становится очень медленным даже на суперкомпьютере, практически использовать эту особенность не представляется возможным.

В следующей таблице 1 во второй колонке указывается название языка, название компилятора и его версия и, если использовалась, опция оптимизации генерируемого кода. В третьей колонке приводится относительное время вычисления на процессоре AMD Phenom II x4 3.2 ГГц. Тесты проводились и на AMD FX-6100 на такой же частоте, но их результаты мало отличаются от приведённых. За единицу принято время вычисления на языке бэш, таким образом, расчёт на эрланге примерно в 20000 раз быстрее бэш. В 4-й колонке приводится относительное время вычисления на процессоре Intel Core i3-2100 3.1 ГГц. Так как сравнение процессоров не было целью исследования, часть трансляторов не были протестированы на платформе Intel. В пятой — оценка сверху (точность 10%) максимального числа рекурсивных вызовов, поддерживаемых транслятором при вычислении ack(1,1,n) на компьютере с 8 Гб оперативной памяти c размером системного стека (ulimit -s) 8192 КБ. Некоторые трансляторы используют собственные настройки, которые определяют размер используемого стека — всегда используются значения по умолчанию для выбранной версии транслятора. Измерения проводились в системе Linux, но их результаты не должны меняться при переходе к другой ОС. Данные отсортированы по 3-й колонке. Все исходники можно посмотреть .

Табл 1.

N Язык AMD Intel Стек
1 C/C++ (gcc 4.7.2, -O5) 354056 493533 790000
2 C/C++ (clang 3.0-6.2, -O3) 307294 270000
3 C/C++ (icc 14.0.3, -fast) 250563 232665 530000
4 Assembler x86-64 243083 271443 350000
5 Assembler x86 211514 301603 700000
6 Java (OpenJDK 1.7.0_25) 186401 239659 8000
7 Pascal (fpc 2.6.0, -O3) 170604 186401 180000
8 C/C++ (gcc 4.7.2, -O0) 159672 173261 180000
9 C/C++ (clang 3.0-6.2, -O0) 146726 110000
10 C/C++ (icc 14.0.3, -O0) 136862 156602 530000
11 Javascript (Mozilla Firefox 25) 121979 4200
12 Javascript (Google Chrome 31) 92850 10000
13 Lisp (sbcl 1.0.57) 54925 51956 31000
14 Erlang (5.9.1) 19845 18589 предела нет
15 Haskell (ghc 7.4.1, -O) 18589 22946 260000
16 Awk (mawk 1.3.3) 6621 6306 44000
17 Lua (5.2) 6420 7075 150000
18 Ruby (1.9.3) 5297 6969 6600
19 Dino (0.55) 5024 6420 190000
20 Basic (Gambas 3.1.1) 3968 4373 26000
21 Python (2.7.3) 3678 4013 1000
22 PHP (5.4.4) 2822 3720 предела нет
23 Awk (gawk 4.0.1) 2648 2547 предела нет
24 Postscript (gs 9.05) 2355 3246 5000
25 Prolog (swipl 5.10.4) 1996 2407 2300000
26 Perl (5.14.2) 1516 1670 предела нет
27 Prolog (gprolog 1.3.0) 1116 1320 120000
28 Lisp (clisp 2.49) 998 1023 5500
29 Awk (busybox 1.20.2) 981 1113 18000
30 T E X (3.1415926) 239 333 3400
31 Metapost (1.504) 235 470 <4100
32 Tcl (8.5) 110 123 1000
33 Haskell (hugs 98.200609.21) 82 121 17000
34 Basic (LibreOffice 3.5.4.2) 20 35 6500
35 bash (4.2.37) 1 0,77 600

В качестве второй задачи выбрана функция Аккермана в форме, когда к ней сводятся все арифметические операции, т. е. ack(1,x,y)=x+y, ack(2,x,y)=x*y, ack(3,x,y)=x y , ack(4,x,y) — тетрация x и y и т. д.

Эта функция с ростом n растёт очень быстро (число ack(5,5,5) настолько велико, что количество цифр в порядке этого числа многократно превосходит количество атомов в наблюдаемой части Вселенной), но считается очень медленно. Последнее свойство теоретически удобно для тестирования быстродействия. Однако, расчет этой функции требует значительного числа рекурсивных вызовов и большинство тестируемых языков оказалось не в состоянии их поддерживать для вычислений, имеющих заметную длительность. Известно, что вычисление этой функции нельзя свести к итерации. Расчет по этой задаче позволил исследовать максимальную ёмкость стека исследуемых языков: расчёт ack(1,1,n-1) требует n-й вложенности вызовов и очень быстр. В следующей таблице 2 представлены результаты расчета пентации ack(5,2,3), для тех языков, стек которых смог его (вложенность вызовов 65539) выдержать. За единицу скорости выбрано время работы gcc с опцией -O5, т. е. php примерно в 420 раз медленнее.

Табл 2.

gcc -O5 1
asm x86 2.15
icc -fast 2.18
asm x86-64 2.36
clang -O3 2.76
fpc -O3 4.44
gcc -O0 7.75
icc -O0 8.36
clang -O0 9.64
Erlang 18.51
ghc -O 50.18
lua 122.55
php 423.64
gawk 433.82
swipl 766.55
dino 915.64

Идея использовать приведённые две задачи позаимствована из труда Б. В. Кернигана и Р. Пайка «Unix — универсальная среда программирования», где она была использована для тестирования языка hoc.

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

Время измерялось стандартной командой time, а тогда, когда это было невозможно (яваскрипт, офисный бейсик) использовались встроенные в язык средства.

По результатам исследования сделаны следующие выводы, некоторые из которых оказались несколько неожиданными:

  1. Скорость работы программ на ассемблере может быть более 50% медленнее, чем программ на си/си++, скомпилированных с максимальной оптимизаций;
  2. Скорость работы виртуальной ява-машины с байт-кодом часто превосходит скорость аппаратуры с кодами, получаемыми трансляторами с языков высокого уровня. Ява-машина уступает по скорости только ассемблеру и лучшим оптимизирующим трансляторам;
  3. Скорость компиляции и исполнения программ на яваскрипт в популярных браузерах лишь в 2-3 раза уступает лучшим трансляторам и превосходит даже некоторые качественные компиляторы, безусловно намного (более чем в 10 раз) обгоняя большинство трансляторов других языков сценариев и подобных им по скорости исполнения программ;
  4. Скорость кодов, генерируемых компилятором языка си фирмы Intel, оказалась заметно меньшей, чем компилятора GNU и иногда LLVM;
  5. Скорость ассемблерных кодов x86-64 может меньше, чем аналогичных кодов x86, примерно на 10%;
  6. Оптимизация кодов лучше работает на процессоре Intel;
  7. Скорость исполнения на процессоре Intel была почти всегда выше, за исключением языков лисп, эрланг, аук (gawk, mawk) и бэш. Разница в скорости по бэш скорее всего вызвана разными настройками окружения на тестируемых системах, а не собственно транслятором или железом. Преимущество Intel особенно заметно на 32-разрядных кодах;
  8. Стек большинства тестируемых языков, в частности, ява и яваскрипт, поддерживают только очень ограниченное число рекурсивных вызовов. Некоторые трансляторы (gcc, icc, ...) позволяют увеличить размер стека изменением переменных среды исполнения или параметром;
  9. В рассматриваемых версиях gawk, php, perl, bash реализован динамический стек, позволяющий использовать всю память компьютера. Но perl и, особенно, bash используют стек настолько экстенсивно, что 8-16 ГБ не хватает для расчета ack(5,2,3). В версии 5.4.20 php стек оказался ограниченным примерно 200000 вызовов.

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

Чтобы написать программы для требуемых расчётов на любом языке, необходимо в первую очередь понять как в конкретном языке объявляются переменные, как построить конструкцию типа if-else и как организовать рекурсию. Свою работу я начал с простого языка Pascal, так как на тот момент знал его лучше всех. После паскаля, я взялся за C, Java и Dino, так как их синтаксисы примерно похожи. С оказался довольно интересным, простым, и в то же время с интуитивно понятными операторами. Ява показался менее удобным, чем си/си++ — надо писать много не относящегося к делу, такого, что могло бы быть взято по умолчанию. Также напряг момент необходимости одинаковости имён класса и файла. От Haskell остались только положительные эмоции. Удобный, понятный и мощный. PHP, язык для разработки веб-приложений, очень похож на С: можно просто вставить код на си с минимальными изменениями и все будет работать так, как надо. Erlang похож по синтаксису на Haskell и немного на Prolog. Тоже довольно приятный и понятный язык, никаких трудностей не возникло. Cинтаксис JavaScript похож на синтасис Java или C. Visual Basic как в офисном, так и GAMBAS исполнении имеет несколько угловатый и неудобный синтаксис, но в целом, с ним было не очень трудно. Затем, после приобретения знаний о базом синтаксисе С и Java, получилось довольно быстро написать код на Python, так как Python схож с С. Никаких проблем не возникло с Lua и его довольно мощными и гибкими конструкциями. У awk также схожее строение с С, довольно быстро удалось его осилить. С лиспом возникли некоторые трудности, как у человека, который до этого изучал С-подобные языки, например, с базовым пониманием префиксной записи. Которая после небольших затрат на освоения, показалась очень удобной, логичной и красивой. После, я перешел на язык логического программирования Prolog, который оказался специфичным, но очень интересным и фундаментальным. Ruby — язык с мощной поддержкой объекто-ориентированного программирования и с очень красивым ярко-красным рубином на иконке оказался превосходным языком: никаких лишних скобок, точек с запятой и прочих ненужных знаков. Один из наиболее запомнившихся. Хотя питон, если не считать конструкций ООП, не менее лаконичен. Perl — хоть и носит название «жемчужина», символом языка является верблюд, что видимо является отсылкой к тому, что верблюд не слишком красивое, но очень выносливое животное, способное выполнять тяжёлую работу. После Ruby опять ставить доллары, скобки и точки с запятой было не очень приятно. Синтаксис местами похож на синтаксис языка терминальной оболочки Bash. Затем я взялся за ассемблер. Здесь были определенные трудности и необходимость понимания работы процессора и его регистров. Удивлению не было предела, когда оказалось, что С справляется с расчётами быстрее чем ассемблер, машинный код! Проблем не возникло с Bash, хоть там и нужно ставить много долларов, а при расчётах и скобок. Язык Metapost/Metafont вызвал некоторые проблемы — там поддерживаются только числа, не большие 4096. Хотя его синтаксис вполне традиционен. У тикля (TCL) тоже довольно традиционный синтаксис, но строчно-ориентированный — это и похожая на bash семантика поначалу очень сбивали с толку. Наиболее сложным показались PostScript. В этом языке синтаксис очень специфичен и без подготовки, интуитивно ничего написать не получится, поэтому пришлось изучать соответствующую литературу и начать тренироваться с самых простейших программок. PostScript был настоящим испытанием: написать двойную рекурсию постфиксной записью лишь при помощи стека, после привыкания ко всем инструментам и возможностям Ruby и C было проблематично. Писать и тестрировать на постскрипте функцию Аккермана, все равно что пытаться покрасить стену зубной щёткой. Но первое место по сложности определенно занимает T E X. Ничего более трудного я не встречал. И без прямой помощи преподавателя одолеть этот язык не получилось бы.

Любопытными оказались данные по размерам стека языков. Чем больше стек языка, тем больше вероятность, что он сможет справиться с функцией Аккермана. Но если программа на каком-то языке не смогла справиться с вычислением ack(5,2,3), это не значит что язык плохой и неудобный. Вполне вероятно, что этот язык мог создаваться для других полезных целей как, например, Metapost или Postscript.

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

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

— Разработаный в России

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

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

Но реальность программирования гораздо сложнее.

Программирование сегодня

Это странно, но большинство действительно “глобальных” идей в компьютерном программировании были разработаны еще в 1950-х и 60-х годах. С тех пор появилось много новых языков, но ни один из них не реализует действительно нового подхода к логике и вычислениям.

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

Некоторые языки были разработаны для решения конкретных проблем в программировании (например PHP и SASS), чтобы управлять определенными типами систем (), или для работы в определенной среде или на определенной платформе (Java и JavaScript). Некоторые языки были разработаны специально для того, чтобы помочь новичкам научиться программировать (классическими примерами являются BASIC и Scratch).

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

Относительно недавнее развитие включает в себя такое понятие, как SOA (Service Oriented Architecture- сервисо-ориентированная архитектура ) и MVC (Model-View-Controller), а также фреймворки, такие как , позволяющие программистам легко работать в рамках этих парадигм.

Список языков программирования

Пополняющийся список популярных языков программирования, разметок и протоколов. Ссылки на описание каждого из них:

Кодировка ASCII

  • Кодировка символов является одним из основных компьютерных и Интернет аспектов. ASCII – это первая, широко использованная система кодировки символов. Она была вытеснена UTF-8, но ASCII по-прежнему является основой для подавляющего большинства символов в Интернете и на сегодняшний день. Понимание этого очень важно для программистов. Читайте подробнее здесь (англ):

ASP / ASP.NET

  • ASP – это аббревиатура для Active Server Pages. Это первый скриптовый серверный язык для веб-сервера Microsoft IIS. ASP был заменен на серверный фреймворк с открытым исходным кодом – ASP.NET. Подробнее (англ):

AutoLISP

  • AutoLISP – это простой, легкий, интерпретируемый язык программирования, созданный специально для автоматизированного проектирования программного обеспечения. Читайте об этом (англ):

Awk

  • Awk является чрезвычайно мощным языком программирования для обработки текстов, позволяющим извлекать данные из файла или другого источника, и выводить их в любом формате, который вам нужен. Он является уже старым инструментом, но все еще так же полезен, как и раньше. Узнайте подробнее (англ): .

BASH

  • Bash – это наиболее часто используемый интерфейс командной строки в мире Unix. Это интерфейс на основе текста по умолчанию и для Linux и для Mac OS X. Подробнее (англ):

Common Lisp

  • Lisp является довольно уникальным языком программирования, возможно, самым древним языком и до сих пор продолжает использоваться. Это особенно важно в области искусственного интеллекта. Подробнее (англ):

C

  • Если мы включим сюда две производные этого языка, то смело можно будет сказать, что ни один язык не проиносил большей пользы и большего влияния, чем С. Это особенно важно для развития операционных систем и другого программного обеспечения. Многие компиляторы и интерпретаторы для других языков написаны на языке C. Подробнее (англ):

C++

  • Первоначально он назывался “C с классами”, C++, во многих отношениях, просто более продвинутый преемник C (хотя в целом ситуация сложнее). C++ был разработан, чтобы добавить высокий уровень парадигмы программирования C, сохраняя при этом возможности аппаратной манипуляции низкого уровня. Многие из этих дополнений добавлялись в C на протяжении многих лет, и языки больше похожи на два диалекта одного и того же языка. Подробнее (англ):

C#

  • Использовался в качестве основного языка для.NET программирования, похож на C++, является расширением языка программирования C, но с важным дополнением в виде объектно-ориентированных возможностей. Подробнее (англ):

CSS / CSS3

  • CSS или Cascading Style Sheets, также не является языком программирования, а языком стиля страницы – это язык, предоставляющий стиль и правила компоновки документам и приложениям. Является основным используемым в Интернете языком стиля. Подробнее:

Emacs Lisp

  • Emacs уже давно был известен как популярный и мощный текстовый редактор. Но добавление в него Emacs Lisp, превращает его в интегрированную среду разработки для почти любого языка программирования. Подробнее (англ): .

F#

  • F# – язык программирования общего назначения. Разработан, чтобы быть чрезвычайно эффективным. Будучи изначально только языком Microsoft, теперь является языком с открытым исходным кодом и используется на всех платформах. Подробнее (англ): .

FORTAN

  • Fortran впервые появился в 1957 году и до сих пор используется для решения некоторых из наиболее сложных проблем современной науки и техники. Подробнее (англ):

FORTH

  • Работа над Forth началась в 1968 году, и язык обычно используется на оборудовании, не имеющем традиционную операционную систему. Он также широко используется для управления станками. Подробнее (англ):

Haskell

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

HTML

  • HTML не является языком программирования. Это язык разметки – язык добавления смысловых и стилистических аннотаций содержимому. Является основным языком для веб-контента. Знание его необходимо и обязательно всем веб-дизайнерам и веб-разработчикам, а также всем (писателям, редакторам), кто производит Интернет контент. Подробнее (англ): и

IDL

  • IDL, или Interactive Data Language, это язык программирования, используемый в основном для анализа и визуализации данных. Он до сих пор широко используется в аэрокосмической промышленности и астрономии. Подробнее (англ):

INTERCAL

  • INTERCAL является пародийным компьютерным языком, разработанным в начале 1970-х годов. Его создали как шутку, чтобы показать как технически сложны языки и трудно читаемы. Это реальный язык, который можно скачать, и с помощью которого можно даже что-то сделать. Подразумевается, что вы должны быть хорошо с ним знакомы для этого – но, опять же, не слишком хорошо, ведь и это не понравится самому INTERCAL. Подробнее (англ):

Java

  • Java является языком высокого уровня и предназначен для использования на Java Virtual Machine. Имеет очень мало внешних зависимостей, и был предназначен для работы на любой физической машине. Много используется в сетевой архитектуре, а также во встраиваемых устройствах и других вычислительных приложениях. Подробнее (англ): .

Javascript

  • JavaScript (не имеет фактического отношения к Java) это скриптовый язык, изначально разработанный для использования в веб-браузерах. Поэтому он имеет встроенную возможность работы с Document Object Model (DOM), отображением находящегося в памяти контента веб-страниц. Является основным языком программирования для front-end веб-разработки. В основном управляется событиями, и, благодаря Node.JS, в последнее время получил признание как серверный язык. Подробнее (англ): и . И здесь:

Ksh

  • Korn Shell (ksh) представляет собой интерфейс командной строки, используемый на Unix. Он был ранней оболочкой (shell), совместимый со стандартной оболочкой Bourne, но со всеми классными интерактивными функциями оболочки C. Подробнее (англ):

Linux Programming

  • Программирование Linux включает в себя все: начиная от скриптов оболочки до разработки приложений и разработки ядер. Подробнее (англ):

Logo

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

ML

  • ML первоначально разработан как язык мета-программирования: язык для создания других языков. Но со временем он стал языком общего назначения, широко использовался в образовании, математике, естественных науках и даже финансах. Подробнее (англ): .

MPI

  • Message Passing Interface (Интерфейс передачи сообщений) представляет собой стандартный протокол для отправки сообщений между процессами или программами. Был реализован в ряде языков программирования, включая C, C++, Java и Python. Благодаря MPI стали возможны параллельные вычисления. Подробнее (англ):

Сетевое программирование с интернет-сокетами

Objective-C

  • Еще одна версия C, созданная в 1980-е годы для того, чтобы обеспечить полностью объектно-ориентированную реализацию C. Сейчас основное применение этого языка приходится на Mac OSX и операционные системы iOS. До недавнего времени iOS приложения должны были быть написаны на Objective-C, но сейчас можно писать также на Swift. Подробнее (англ):

OCaml

  • OCaml является объектно-ориентированным функциональным компьютерным языком. По ML традиции, он много используется для написания других языков программирования и фреймворков. Подробнее (англ): .

Разработка операционной системы

  • Эверестом среди работ по программированию считается разработка операционной системы. Если вы хотите доказать себе, что можете написать все, что угодно, то нет ничего лучше, чем написать свое собственное ядро операционной системы и связанные с ней инструменты.Но будьте осторожны: это путешествие по силам только храбрым и истинным программистам! Подробнее (англ): .

Perl

  • Очень полезный инструмент практически любого программиста. В качестве интерпретируемого языка его не нужно компилировать, иногда упоминается как “швейцарский армейский нож” скриптовых языков. Подробнее (англ):

PROLOG

  • Пролог – язык логического программирования, разработан для обработки естественного языка. Подробнее (англ):

Pure Data

  • Pure Data является уникальным визуальным языком программирования. Был создан специально для того, чтобы позволить пользователям создавать видео, аудио и графические работы. Подробнее (англ): .

Python

  • Python является языком программирования высокого уровня. Интерпретируемый (некомпилируемый) язык, также известный как “скриптовый язык”. В основном используется в качестве инструмента для выполнения специализированных задач программирования, таких как задачи по автоматизации и анализу данных. Имеет сильный набор инструментов для математических и научных вычислений, часто используется исследователями. Подробнее (англ):

Ruby on Rails

  • Ruby on Rails – это фреймворк для веб-разработки для языка программирования Ruby. Он обеспечивает архитектуру MVC (Model View Controller), уровень абстракции базы данных, а также множество инструментов для ускорения процесса программирования веб-приложений. Очень популярен для быстрой разработки веб-приложений. Подробнее (англ):

SAS

  • SAS является специализированным языком, предназначенным для анализа статистических данных. Широко используется в правительственных, научных кругах и бизнесе. Для людей, обладающим большим количеством данных, SAS является очевидным выбором. Подробнее (англ): .

Scala

  • Scala является относительно новым языком – более или менее новой и лучшей Java. Это отличный язык для Java-программистов, которые хотят быть более эффективными, или для людей, кто только начинают изучать программирование и хотят изучать мощный язык, который не будет ограничивать их в будущем. Подробнее (англ): .

Scheme

  • Scheme – старый язык, но до сих пор используется для обучения программированию и более сложных предметов в информатике. Основан главным образом на Lisp, и частично на ALGOL. Подробнее (англ): .

Scratch

  • Язык программирования Scratch был создан специально для обучения программированию детей в возрасте от 8 до 16 лет. Scratch – легкий, и с ним изучать основы логики программирования детям можно в увлекательной игровой форме. Подробнее (англ):

Simula

  • Simula – исторически важный язык, так как это был первый язык, внедривший понятия, ставшие основой для объектно-ориентированного программирования. Подробнее (англ): .

SMIL

  • SMIL (Synchronized Multimedia Integration Language) инструмент для тех людей, которые хотят создавать и распространять презентации. Особенно полезен, если вы хотите создавать презентации, которые должны время от времени обновляться. Подробнее (англ):

SQL

  • SQL (Structured Query Language) – язык, используемый для связи с Relational Database Management Systems (RDBMSes). SQL позволяет программисту создавать структуры данных, вставлять и редактировать данные, а также их запрашивать. Подробнее (англ):

Stata

  • Stata это среда разработки и язык программирования для решения серьезных статистических проблем. И хотя он создан довольно давно, но все еще широко используется. Если вы связаны со статистической работой, Stata – отличный инструмент. Подробнее (англ):

Swift

  • Swift является новыйм языком программирования, разработанным компанией Apple, для iOS, OS X, watchOS, tvOS и Linux. Это язык будущего для разработчиков программ и приложений для устройств Apple. Подробнее (англ):

S-PLUS

  • S-PLUS является коммерческой версией мощного языка программирования S, разработанного для выполнения статистического анализа. Проект GNU имеет свою собственную версию S, называемую R. Все необходимые ресурсы о S с акцентом на S-PLUS:

UNIX Programming

  • Широта программирования на Unix велика. Она охватывает диапазон от административных скриптов к коду на основе текста до разработки X Window. Подробнее (англ):

XML

  • XML хорошо структурированный язык для разметки, предназначен, как для чтения человеком, так и машиной. Подробнее (англ):

Урок подготовил: Акулов Иван

Программисты и ученые, как правило, пристрастны, когда речь заходит о достоинствах и недостатках различных языков программирования. Сравнив несколько языков, автор попытался получить объективную информацию о Си, Си++, Java, Perl, Python, Rexx и Tcl.

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

В ходе сравнительного исследования сопоставлялись различные аспекты каждого языка, в том числе длина программы, усилия, затраченные на программирование, время выполнения, занимаемое пространство памяти и надежность. Языки сравнивались индивидуально и по группам. Языки сценариев, такие как Perl, Python, Rexx и Tcl чаще интерпретируются, чем компилируются (по крайней мере, на этапе разработки программ), и обычно не требуют определения переменных.

Более традиционные языки программирования - Си, Си++ и Java - чаще компилируются, чем интерпретируются и требуют описания типов переменных. Поскольку многие считают язык Java очень неэффективным, я иногда относил Си и СИ++ к одной группе, а Java к другой.

Диаграммы и статистические методы

В качестве основного инструмента оценки в статье используется блочная диаграмма, показанная на рис. 1. Каждая линия представляет одно подмножество данных, имя которого указано слева. Каждым малым кружком обозначено одно значение данных. Остальная часть диаграммы помогает визуально сравнить два или несколько подмножеств данных. В затененном блоке заключена средняя половина значений, между верхними границами первой четверти (25%) и третьей четверти (75%). «Усы» слева и справа от блока показывают нижние и верхние 10%, соответственно. Жирная точка внутри блока - верхняя граница второй четверти (50%). Символ «M» и разорванная линия вокруг него показывает среднее арифметическое, плюс/минус среднеквадратическую ошибку.

Рис. 1. Время работы программы с набором данных z1000
Исполнение трех программ было завершено безрезультатно по истечении примерно 21 минуты. Разброс отношений «плохих и хороших величин» составляет от 1,5 для Tcl до 27 для Си++. Обратите внимание на логарифмический масштаб оси. Пояснения к данному рисунку относятся также к Рис. 2-7. Более подробное описание дано в разделе «Диаграммы и статистические методы»

Для количественного описания разброса значений в группе было использовано отношение «плохих и хороших величин»: представьте, что данные разделены между верхней и нижней половинами, и отношение «плохих и хороших величин» представляет собой частное от деления среднего значения верхней половины на среднее значение нижней половины. На блочной диаграмме средним считается значение, полученное в результате деления величины у правого края блока на величину у левого края блока. В отличие от такой меры разброса величин, как среднеквадратичное отклонение, отношение «плохих и хороших величин» эффективно исключает резкие выбросы.

Самый важный вывод можно сделать непосредственно из диаграммы. Однако для перепроверки были выполнены статистические тесты. Для сравнения средних значений используется односторонний U-критерий Манна-Уитни (также называемый критерием суммы рангов Уилкоксона). Результат каждого теста - p, величина, характеризующая вероятность того, что наблюдаемая разница между двумя выборками лишь случайна, и что в действительности различия между двумя группами величин отсутствуют или имеют противоположный знак. Обычно само p-значение не приводится, а в тексте статьи указывается «... больше, чем...», если 0 0,10, то «существенных различий нет».

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

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

Результаты

Для оценки программ использовались три различных входных файла: z1000, содержащий 1000 непустых случайных телефонных номеров; m1000, содержащий 1000 произвольных случайных телефонных номеров, некоторые из которых могли быть пустыми; и z0, не содержащий телефонных номеров и служащий исключительно для измерения времени загрузки словаря.

Время выполнения программы

Я начал анализ с измерения полного времени выполнения, а затем исследовал отдельно этапы инициализации и поиска.

Полный набор данных z1000. Как показано на рис. 1, время выполнения всех программ за исключением Си++, Java и Rexx, составляет менее 1 мин. Сравнивая данные, можно сделать несколько значимых выводов.

  • Среднее время выполнения программ Tcl незначительно больше, чем Java и даже Си++.
  • Среднее время выполнения как для Python, так и для Perl меньше, чем Rexx и Tcl.
  • Средний показатель Си++ может ввести в заблуждение. Из-за довольно большого разброса между соседними большими и меньшими величинами, среднее значение нестабильно. Критерий Уилкоксона, который учитывает весь набор данных, подтверждает, что среднее время для Си++, как правило, меньше среднего времени для Java (p = 0,18).
  • Среднее время выполнения для Си меньше, чем для Java, Rexx и Tcl, и как правило, меньше чем для Perl и Python.
  • Время выполнения для Tcl и Perl - за исключением двух очень медленных программ - как правило, более стабильно, чем время выполнения программ на других языках.

Не следует придавать особенно большого значения диаграммам для Си и Rexx, построенным всего по нескольким точкам. Время выполнения программ на Rexx может быть снижено примерно в четыре раза, если перекомпилировать интерпретатор Regina для использования хеш-таблиц большего размера; требования к памяти при этом возрастают незначительно. Если объединить языки всего в три группы (одна - Си и СИ++ , вторая - Java, третья - языки сценариев), то программы на Си и Си++ работают быстрее, чем Java (p = 0,074), и как правило, быстрее сценариев (p = 0,15).

Между средним временем выполнения программ на Java и сценариев нет существенной разницы. С вероятностью 80% сценарий будет выполняться в 1,29 раза дольше - а программа на Java по меньшей мере в 1,22 раза дольше - чем программа на Си или Си++. Отношение «плохих и хороших величин» значительно меньше для сценариев (4,1), чем для Java (18) и даже для Си и Си++ (35).

Только этап инициализации, набор данных z0. Затем я измерил время, необходимое для считывания, предварительной обработки и сохранения словаря. Соответствующие времена приведены на рис. 2. Результаты явно свидетельствуют, что Си и Си++ выполняют эту фазу быстрее, чем другие протестированные языки. И вновь, самыми быстрыми языками сценариев оказались Perl и Python. Как выяснилось (с вероятностью 80%) при сравнении укрупненных групп, программа на Java будет выполняться по крайней мере в 1,3 раза дольше, чем программы на Си и Си++, а для выполнения сценария потребуется по крайней мере в 5,5 раз больше времени. Сценарий будет выполняться по крайней мере в 3,2 раза дольше программы на Java.

Рис. 2. Время, затраченное программой только на загрузку и предварительную обработку словаря (набор данных z0). Обратите внимание на логарифмический масштаб оси. Соотношение «плохих и хороших величин» в пределах от 1,3 для Tcl до 7,5 для Python

Только этап поиска. И наконец, я вычел время время этапа загрузки (набор данных z0) из полного времени выполнения (набор данных z1000), чтобы получить время только поискового этапа программы. На рис. 3 показаны соответствующие времена, из которых можно сделать следующие выводы.

  • Очень быстрые программы составлены на всех языках, за исключением Rexx и Tcl, а очень медленные программы встречаются на всех языках.
  • Среднее время выполнения программ на Tcl больше, чем время программ на языках Python, Perl и Си, но меньше, чем на Rexx.
  • Среднее время выполнения программ на Python меньше, чем времена для Rexx и Tcl, и как правило, меньше, чем время выполнения Java (p = 0,13).
  • Среднее время выполнения программ на Perl меньше средних показателей для Rexx, Tcl и Java.
  • Среднее время Си++ существенно отличается от результатов любого другого языка.

Рис. 3. Время, затраченное программой только на поиск, вычисленное как разность между временем работы с набором данных z1000 и набором данных z0. Обратите внимание на логарифмический масштаб оси. Соотношение «плохих и хороших величин» в пределах от 2,9 для Perl до 50 для Си++

Сравнение укрупненных групп свидетельствует об отсутствии серьезных различий между любыми группами. Однако можно с вероятностью 80% утверждать, что разброс времени выполнения сценариев по крайней мере в 2,1 раза меньше, чем у Java, и по крайней мере в 3,4 раза меньше, чем у Си и Си++.

Требования к памяти

На рис. 4 показан общий размер процесса в конце обработки входного файла z1000. Из него можно сделать несколько выводов.

  • Очевидно, что наиболее эффективно память используется в программах групп Си и Си++, а наименее эффективно - в программах группы Java.
  • За исключением Tcl, лишь немногие сценарии потребляют больше памяти, чем худшая половина программ на Си и Си++.
  • Для сценариев Tcl требуется больше памяти, чем для других сценариев.
  • Относительный разброс требований к памяти программ на Python и Perl, как правило меньше, чем программ на Си и в особенности Си++.
  • Некоторые сценарии занимают большие области памяти.
  • При сравнении укрупненных групп можно утверждать с вероятностью 80%, что в среднем программы на Java занимают по крайней мере на 32 Мбайт больше памяти (297%), чем программы на Си и Си++, и по крайней мере на 20 Мбайт больше (98%), чем сценарии. Сценарии занимают по крайней мере на 9 Мбайт больше памяти (85%), чем программы на Си и Си++.

Рис. 4. Объем памяти, необходимый программе, в том числе для размещения интерпретатора или исполняющей системы, собственно программы и всех статических и динамических структур данных. Соотношение «плохих и хороших величин» в пределах от 1,2 для Python до 4,9 для Си++

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

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

Длина программ и число комментариев

На рис. 5 показано число строк исходного файла каждой программы, в которых содержится любая семантическая информация программы: операторы, определения или по крайней мере разделители, такие как закрывающая фигурная скобка. Несценарные файлы обычно вдвое или втрое длиннее сценариев. Даже самые длинные сценарии короче средних несценарных исходных текстов. Вместе с тем, плотность комментариев в сценариях значительно выше (p = 0,020): в несценарных программах в среднем содержится на 22% больше строк с комментариями, чем строк с операторами; для сценариев этот показатель составляет 34%.

Рис. 5. Длина программы: число строк исходного текста без комментариев. Соотношение «плохих и хороших величин» в пределах от 1,3 для Си до 2,1 для Java и 3,7 для Rexx

Надежность программ

При работе с входным файлом z1000 три программы - одна на языке Си, одна на Си++ и одна на Perl - не выдали корректных результатов, поскольку не могли загрузить большой словарь или из-за истечения времени, отведенного на завершение этапа загрузки. Две программы на Java имели почти нулевую надежность и отказали по другим причинам; а одна программа на Rexx выдала много результатов, используя некорректный, только форматирующий сценарий - ее надежность составила 45%.

Отбросив эти явно ошибочные программы - тем самым, были исключены 13% программ на Си и Си++, 8% программ на Java и 5% сценариев - и сравнив остальные по языковым группам, мы обнаружили, что программы на Си и Си++ менее надежны, чем Java и сценарии. Однако эти различия были вызваны лишь несколькими программами с дефектами и потому не могут служить основанием для общих выводов.

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

Затем я сравнивал поведение при работе с входным файлом m1000, в котором могут содержаться телефонные номера без цифр, лишь с тире и наклонными чертами. Такие телефонные номера должны преобразовываться в пустые записи, но программисты склонны забывать о таких требованиях, читая задание. Поэтому на файле m1000 проверяется добротность программы. Большинство программ успешно справились с этой ситуацией, но половина программ Java и четыре сценария - один Tcl и три на языке Python - зависли на первом пустом телефонном номере, после того, как было выдано 10% результатов. Обычно сбой происходил из-за неправильного индекса строки или массива. Среди прочих программ, 15 - одна составленная на Си, пять Си++, четыре Java, две Perl, две Python и одна Rexx - не смогли обработать пустые телефонные номера, но в остальном работали корректно; их надежность составила 98,4%.

В целом, надежность сценариев, по-видимому, не ниже надежности несценарных программ.

Время работы и продуктивность труда

На рис. 6 показано общее время, затраченное на проектирование, составление и тестирование программы, сообщенное авторами сценариев и измеренное для программистов несценарных программ.

Рис. 6. Полное время, затраченное на реализацию программы
Программисты сценарной группы измеряли и сообщали время работы: время языков «несценарной» группы измерялось экспериментатором. Соотношение «плохих и хороших величин» в пределах от 1,5 для Си до 3,2 для Perl. Три величины для Java - рабочее время 40, 49 и 63 час - выходят за границы диаграммы и потому не показаны.

Мы обнаружили, что время составления сценариев с общей медианой 3,1 часа более чем вдвое меньше, чем несценарных программ с общей медианой 10,0 часов, хотя вероятно, различие преувеличено из-за неполной достоверности эксперимента.

К счастью, можно одновременно проверить два фактора, а именно, корректность сообщений о времени, затраченном на составление программ, и равенство квалификации программистов в сценарной и несценарной группах. Оба этих фактора, если они действительно играют роль, должны способствовать снижению времени работы сценарной группы: я предполагаю, что субъективные сообщения будут содержать уменьшенное, а не преувеличенное время работы программы, а в случае появления различий мы ожидали обнаружить более квалифицированных программистов в сценарной группе, поскольку в 1997 и 1998 годах, когда проводилось исследование, программисты Java были менее опытными, чем специалисты по другим языкам. В основу данной проверки положено старое практическое правило, согласно которому число строк исходного текста, выдаваемых программистом в час, не зависит от языка программирования. В нескольких широко применяемых методах оценки трудозатрат - в том числе Cocomo Барри Боэма и таблицах языков программирования для оценки функциональных точек Кейперса Джонса - явно предполагается, что почасовое число строк исходного текста не зависит от языка программирования. На рис. 7 показаны оценки рабочего времени, составленные на основе этого правила. Судя по достоверно известному диапазону продуктивности при работе с Java, все величины, за исключением трех лучших результатов для Tcl и лучших времен для Perl, выглядят правдоподобно.

Рис. 7. Число строк исходного текста, написанных за полный рабочий час. Соотношение «плохих и хороших величин» в пределах от 1,4 для Си до 3,1 для Tcl

Ни одно из медианных различий не имеет явной статистической значимости, хотя отличия Java от Си, Perl, Python и Tcl (0,07

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

Структура программы

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

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

Более изощренный подход состоит в использовании 10-арного дерева, каждый узел которого представляет определенную цифру, а узлы на высоте n представляют n-ный символ слова. Слово хранится в узле, если путь от корня к данному узлу представляет числовой шифр слова. Это решение - самое эффективное, но для построения и прохождения дерева требуется сравнительно большое число операторов. В Java многочисленность результирующих объектов приводит к большому расходу памяти из-за необходимости выделять чрезвычайно крупные области для хранения каждого объекта в текущих реализациях среды исполнения Java-программ.

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

Хотя хеш-таблицы реализованы в библиотеках классов как для Java, так и для Си++, ни один из программистов, работающих с несценарными языками не воспользовался ими, предпочитая строить дерево вручную. И наоборот, авторы сценариев с готовностью применяют встроенные в их языки хеш-таблицы.

Важнейшие выводы

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

  • Проектирование и составление программ на языках Perl, Python, Rexx и Tcl занимает не более половины времени, необходимого для программирования на Си, Си++ и Java - а длина исходного текста вдвое меньше.
  • Явных различий в надежности между программами различных языковых групп не обнаружено.
  • Типичный сценарий занимает примерно вдвое больше памяти, чем программа на Си или Си++. Программы на Java занимают втрое и вчетверо больше памяти, чем программы на Си и Си++.
  • Программы на Си и Си++ выполняют инициализацию программы преобразования телефонных номеров, которая заключается в считывании словарного файла размером в 1 Мбайт и построении 70-килобайтной внутренней структуры данных, в три или четыре раза быстрее, чем программы на Java и примерно в пять или десять раз быстрее, чем сценарии.
  • На основном этапе программы преобразования телефонных номеров ведется поиск во внутренней структуре данных, и программы на Си и Си++ работали всего примерно вдвое быстрее Java. Сценарии, как правило, работают быстрее программ на Java.
  • Среди сценарных языков Perl и Python выполняли оба этапа быстрее, чем Tcl.
  • Разброс любых исследованных параметров программ, возникший вследствие различий между программистами, работающими на одном языке - отраженный отношениями «плохих и хороших величин» - в среднем такой же или больше разброс характеристик, вызванного различиями языков.

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

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

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

Лутц Прехельт ([email protected]) - руководитель службы контроля качества компании abaXX Technology (Штуттгарт, Германия).

Литература

1. E. Bradley and R. Tibishirani, «An Introduction to the Bootstrap,» Monographs on Statistics and Applied Probability 57, Chapman and Hall, New York, 1993
2. L. Prechelt, An Empirical Comparison of C, C++, Java, Perl, Python, Rexx and Tcl for Search/String-Processing Program, Tech Report 2000-5, Fakultat fur Informattik , Universitat Karlsruhe, Germany, Mar. 2000.
3. B.W. Boehm, Software Engineering Economics, Prentice Hall, Englewood Cliffs, N.J., 1981
4. C. Jones, Software Productivity Research , Programming Languages Table, Version 7, 1996.

An Empirical Comparison of Seven Programming Languages, Lutz Prechelt, IEEE Computer, October 2000, pp. 23-29. Copyright IEEE CS, Reprinted with permission. All rights reserved.

Достоверность сравнения

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

Программы получены из двух различных источников. Программы на Java, Си и Си++ были составлены в 1997 и 1998 годах во время контролируемого эксперимента, в котором участвовали студенты старших курсов факультета вычислительной техники (L. Prechelt and B. Unger, A Controlled Experiment on the Effects of PSP Trimming: Detailed Description and Evaluation, Tech Report 1/1999, Fakultat fur Informattik, Universitat Karlsruhe, Germany, Mar. 1999). Программы на Perl, Python, Rexx и Tcl были составлены в различных условиях добровольцами, которые откликнулись на приглашение, опубликованное в нескольких конференциях. Поэтому авторы имели разные уровни подготовки и опыт.

Квалификация программистов

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

В несценарной группе программисты на Java имели меньший опыт работы со своим языком, чем программисты на Си и Си++, поскольку в 1997 и 1998 годах Java был еще новым языком. В сценарной группе программисты на Perl имели более высокую квалификацию, чем другие участники эксперимента; по-видимому, язык Perl привлекает особенно талантливых программистов - по крайней мере, таково мое личное впечатление.

Точность измерения времени работы

Мы точно знаем время программирования в условиях контролируемого эксперимента с несценарными языками, однако ничто не мешало авторам сценариев занизить время, потраченное ими на составление программ. Хуже того, некоторые из авторов, очевидно, приступили к работе спустя много дней после того, как ознакомились с требованиями, предъявляемыми к программам. Один программист сообщил, что начал составлять программу через две недели после прочтения объявления «... в это время подсознательно я мог уже работать над решением.»

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

Различие задач и условий работы

Главным требованием к несценарной группе была правильность программы; приемный контроль подразумевал высокую надежность и по меньшей мере некоторую степень эффективности.

К сценарной группе наряду с главным критерием корректности предъявлялись восемь дополнительных качественных требований. Вместо приемного контроля несценарной группы авторам сценариев были предоставлены входные и выходные данные z1000 для собственного тестирования. В обоих случаях различия могут дать преимущество сценарной группе.

Выводы

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