Dmitry Astapov (_adept_) wrote,
Dmitry Astapov
_adept_

Category:

Языки программирования в условиях, приближенных к боевым

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

Кульминацией этой переписки стало то, что он предложил мне следующее пари: я формулирую простенькую задачу, после чего мы оба реализуем ее - он на С, я - на Haskell. После этого в условие вносятся небольшие коррективы (моделируем поведение требований в реальном мире), а мы вносим коррективы в наши программы. Результаты сравниваются по скорости исполнения, объему потребляемой памяти, количеству строк кода.

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

Моя первая версия активно использовала Data.Generics и библиотечные парсеры на их основе, поэтому выиграла в размере и читаемости кода, но пролетела по объему потребляемой памяти. Впрочем, мой оппонент настолько понадеялся на мощь C, что решил не использовать библиотечный qsort, а реализовать insertion sort самостоятельно. Это самым пагубным образом сказалось на производительности (LOCs - строки кода, память - в мегабайтах, время - в секундах):


LOCs MEM max Runtime, sec
Haskell, v1 72 580 88
C++, v1 861 55 383


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

В результате я тоже решил "срезать углы", и принести красоту кода в жертву скорости. Мой же оппонент взялся за qsort, и к вторые (финальная) версии нашего кода "финишировали" с такими результатами:


LOCs MEM max Runtime, sec
Haskell, v2 169 130 8
C++, v2 950 54 5


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


К чему я все это веду?

Существует классическая статья "Haskell vs. Ada vs. C++ vs. Awk vs. ... An Experiment in Software Prototyping Productivity", написанная в 1994-м году. За 15 лет многое изменилось, и, думается, многим было бы интересно прочитать подобную статью про положение дел сегодня.

В связи с этим ищутся:
1)Условия подходящей задачи (критерии см. ниже)
2)Желающие реализовать ее на Haskell/C+/Ocaml/Java/Scala/C#/... с тем, чтобы ваш код был нещадно сравнен с другими и опубликован для всеобщего обозрения.


Q:Зачем все это делается?
A:На других посмотреть, себя показать. В частности, чтобы люди имели возможность посмотреть на решения на других языках, и составить о них какие-то мнение.

Q:Чем не устраивает The Great Language Shootout?
A:Тем, что там отдается предпочтение "быстрым и грязным" решениям, которые всячески "срезают углы". Во-первых, в таком стиле пишется дай бог чтобы 5% от всех программ, во-вторых, людям, не знающим язык X, строго противопоказано смотреть на решения на языке X в Language Shootout - останется превратное впечатление.

Q:Как будут сравниваться решения, чтобы определить победителя?
A:Никак, т.к. победителей не будет. Будут приведена определенная статистика по всем решениям, без выводов.

Q:Какой тогда стимул участвовать?
A:На других посмотреть, себя показать :)

Какой должна быть задача?
1)Не заточенной под конкретную ОС (т.е. "Реализовать компонент, встраеваемый в Word" или "плагин для libpam" - не катит)
2)Не заточенной под конкретный язык/фреймворк/... (т.е. "получить список сигнатур методов всех объектов указанной сборки .Net" - не катит)
3)Если глубокие знания в предметной области дают решающее преимущество - это fail (т.е. "реализовать DES-CBC" - не катит)
4)Чтобы она не была из категории "мне не нужно, чтобы плац был чистый, а нужно, чтобы вы задолбались" (т.е. "распарсить XLS-файл, не пользуясь библиотеками" - не катит)
5)Задача не должна требовать много времени на реализацию (если это будут человеко-недели - никто за нее не возьмется)

Какой должна быть реализация?
1)Чтобы ее было не стыдно показать другим. В частности, чтобы решение на языке X не заплевали бы как кривое и неидиоматичное другие программисты, знающие язык X.
2)Идеально было бы давать две реализации: первую с ориентиром на "красоту", "образцово-показательность" и легкость поддержки/развития кода (т.е. пишем как пример кода, который будет прилагаться к резюме :), а вторую - "грязную и быструю".
3)Т.к. библиотеки - это неотъемлимая часть силы и популярности языка, библиотеками "общего назначения" (контейнеры, парсинг, ...) пользоваться можно и нужно
4)Но! Решение, которое свелось к исключительно к нахождению и использованию какой-то (узкоспециальной) библиотеки никому не интересно и рассматриваться не будет.

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

Если у вас есть идея подходящией задачи и вы хотите ей поделится - напишите комментарий, а?
Tags: fprog.ru, request
Subscribe
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 111 comments