Чисто навскидку хочется сказать, что оптимальная программа — это та, которая работает максимально быстро. Самую малость поразмыслив, понимаешь, что надо бы дополнить: при этом ещё и правильно. Уже одно только это дополнение несколько портит всю очевидность ситуации. Действительно, которая программа оптимальнее, быстро работающая и дающая ошибку один раз на миллион или работающая чуть медленнее, но ошибающаяся раз на десять миллионов? Да хрен знает. Общего случая тут нет, есть только конкретные случаи с разными ценами ошибок, что и определяет как раз означенное понятие оптимальности.
Наиболее одарённые тут обычно говорят: оптимальнее всего программа, которая работает без ошибок и максимально быстро. Что сразу же наталкивает на рассуждения о сферических конях в абсолютном вакууме. То бишь, в случае с программами, о примитивных синтетических задачах, кои как раз и составляют основу суждений одарённых, но не имеют к реальному миру никакого отношения. И это, к слову, упирается в вопрос цены, в чём бы мы её там ни считали — в деньгах ли, по капиталистически, или в человеко-часах по коммунистически, всё одно, вопрос цены краеуголен и всеопределяющ.
Мини-алгоритм, типа сортировки массива вполне возможно написать без ошибок. Просто потому, что физически возможно за крайне небольшое время сто раз к ряду проанализировать каждую строку программы. Совокупность алгоритмов на сто тысяч строк кода физически невозможно внимательно проанализировать даже один раз. То есть, физически возможно — за сто лет, например, — но вот за короткий срок, увы…
Количество ошибок по отношению к длине кода возрастает нелинейно (за счёт роста количества взаимосвязей между логическими блоками). Таким образом, если исправление ошибок в коде из десяти строк потребует, скажем, десяти минут, то для тысячи строк это будет уже не тысяча минут, а, скажем, десять тысяч. Даже при архи-грамотном проектировании и написании кода мега-квалифицированным программистом, число ошибок в отношении к длине кода всё равно будет расти. Равно будет расти и время на их исправление. Это — первый аспект проблемы.
Второй её аспект — стоимость непосредственно разработки, без учёта исправления ошибок. Как бы быстро программист ни печатал, ему всё равно придётся печатать. И время, требующееся чисто на запись мыслей в текстовый файл с программой будет пропорционально количеству того, чего ему надо написать. Сами по себе мысли, обратно, по мере роста функциональности программы будут требовать время на своё появление. И это время снова нелинейно зависит от длины кода, за счёт всё тех же взаимосвязей.
Таким образом, увеличение длины кода будет нелинейно увеличивать время на его разработку, вне зависимости от квалификации программиста. Да, у квалифицированного на всё вышеперечисленное уйдёт радикально меньше времени, чем у абы у кого, однако время это всё-таки уйдёт. И стоимость программы, как легко догадаться, в конечном счёте от этого дела будет зависеть напрямую.
К чему я это? К тому, что если, выражаясь по капиталистически, ускорение программы на десять процентов будет стоить два дополнительных месяца работы, при этом зарплата программиста — две тысячи баксов, а стоимость более мощного проца — триста баксов, то выгоднее купить более мощный проц и оставить на десять процентов более медленный алгоритм. В человеко-часах ровно так же.
Этот частный случай с длиной алгоритма плавно и неуклонно обобщается. Положим, код на языке С выполняется в три раза быстрее аналогичного на Java, но требует в два больше раза времени на свою разработку. Считаем, что дороже — проц под ускорение или удвоение времени разработки и делаем вывод. Как правило, вывод не в пользу С.
По крайней мере, в тех случаях, когда процом вообще возможно решить проблему, что бывает, конечно, не всегда.
Идём далее. Выясняем, что понимается под «скоростью выполнения». Точнее, про скорость выполнения чего именно идёт речь. А речь обычно идёт про синтетический тест вида: «берём цикл и n раз множим в нём икс на один». В этом случае, да, на С раз в сто быстрее. Но на практике у нас нет программ, где n раз множится икс на один. А даже если мы что-то и считаем таким образом — через мини-программу, то нам, собственно, обычно пофиг, минуту она будет работать или две. Мы один раз это дело посчитаем и больше данный код никогда не запустим. Нам, собственно, гораздо более критично, за сколько времени мы оный код напишем. Ибо если на код уйдёт час вместо десяти минут, то буде он даже потом за десять секунд вместо минуты выполнится, мы всё равно около сорока девяти минут потеряли: не на расчёт — на написание кода.
В реальности у нас крайне редко есть уже готовый, заполненный массив, который теперь надо просуммировать. Обычно у нас ещё есть место, где этот массив заполняется. И в зависимости от рода заполнения может статься, что не смотря на некоторую тормознутость какого-нибудь ArrayList-а при итерации по всем элементам на фоне массива, на сумме заполнения и потом итераций мы всё равно по времени выиграем. Хотя в синтетическом тесте производительности массива и ArrayList-а первый дал аж десятикратный прирост скорости.
Логика тут вполне очевидная: сыпятся, положим, нам откуда-то числа. А мы их пихаем в массив, по которому потом собираемся итерироваться. Мы заранее не знаем, сколько чисел отсыпят. Какой выход? Выходов три. Первый — попросить отсыпать одно и то же два раза. На первый раз узнать размер массива, а на втором его с нужным размером создать и заполнить. Однако тут мы пропипали всю производительность за счёт двойного запроса, который может происходить сколь угодно медленно. Второй выход — завести массив немерянных размеров и засыпать в него пришедшее, забив на оставшуюся в конце массивов безграничную пустоту. Тут мы, соответственно, пропипём немерянно памяти, всё равно сохранив вероятность с размером немерянности массива не угадать и вылететь за его пределы при отсыпании чисел. Наконец, третий вариант — использовать не массив в чистом виде, а обёртку над ним. Которая будет внутренний массив оперативно подгонять под требуемый размер.
Третий случай, конечно, работает медленнее, чем массив с заранее заданным размером, в который напрямую пихают числа. Но при этом он быстрее двойного запроса, безопаснее в смысле неугадывания размера и потребляет меньше памяти. Легко догадаться, что в среднем следует использовать именно его. Если же итерации весьма и весьма часты, то следует либо после заполнения массив из обёртки извлечь и пользоваться им, либо же внутри обёртки грамотно предусмотреть итерирование — например, в виде итерирования напрямую по массиву с вызовом переданной функции по ссылке (или по безымянной имплиментации интерфейса в случае с Java).
Мы видим, что не смотря на очевидное преимущество массива в синтетическом тесте, реальная задача для своего оптимального решения прямо-таки потребовала обёртки над массивом. Более того, если бы мы упёрлись в массив, поскольку он быстрее в синтетическом тесте работал, то наше решение работало бы медленнее. Подчеркну: работало бы медленнее, а не просто было бы более трудоёмким в реализации.
Низкоуровневые языки позволяют отлично соптимизировать каждый отдельный маленький фрагмент задачи. Высокоуровневые позволяют отлично соптимизировать их совокупность.
В ряде случаев мы действительно можем заранее узнать количество объектов, однако в ряде других случаев — не можем. И этот другой ряд требует несколько иного подхода, как бы «заставляя» нас сменить массив на некоторую его обёртку. Дополнительные задачи «заставляют» эту обёртку усугублять. Так, например, поиск элемента по ключу не просто более трудоёмок без мапов, он ещё и работает существенно медленнее при прямом переборе всех элементов массива на фоне поиска через хэш.
Возможность организовать некие данные в структуру не только упорядочивает код, но и позволяет передать кучу данных разом — по ссылке, а не создавать копию каждой переменной для передачи в функцию по значению. Использование структур в результате не только тормозит некоторые фрагменты программы, но и ускоряет другие. Вкупе с другими плюшками — выигрыш. Однако возникает проблема времени жизни этих структур-объектов. Через некоторое время она становится настолько масштабной, что половина времени уходит на разруливание вопросов с управлением этим самым временем жизни. И 90% багов, обратно же, концентрируется в этой области. При этом былых багов вовсе не стало на 90% меньше. О нет, новые баги — новые. Они не за счёт исчезновения всех старых.
Для приведения оного беспредела к сколь либо приемлемому состоянию программист для начала вводит фабрики. Потом, осознав, что объекты всё равно приходится вовремя удалять, делает подсчёт ссылок. Подсчёт ссылок из отдельных объектов переползает в некоторый менеджер и… Этот менеджер — сборщик мусора и есть. Только работает он гораздо медленнее явовского и глючит временами. Оно и понятно: времени-то на отладку и оптимизацию у программиста не было. В потенциале, само собой, он благодаря доступу к низкому уровню имел возможность написать свой турбо-быстрый сборщик мусора, однако в среднем он написал не его, а что-то совсем другое, несравнимое.
Сборщик мусора, вдобавок, быстрее очищает память, чем последовательный вызов delete для всех по очереди объектов, поскольку имеет возможность очищать некоторый блок памяти целиком, в одно действие. Так что для полной имитации оного надо ещё и менеджер памяти свой делать.
Объекты и прочие абстрактные концепции падают не с неба, не являются следствием повального снижения квалификации, напротив, их появление вызвано оной квалификации неуклонным ростом. Опытный программист рано или поздно начинает осознавать необходимость такого рода абстракций, нужных не только за ради простоты работы, но и за ради эффективности результата. А вот уже в следствие введения абстракций появляется возможность занять некоторой работой тех, кто ранее по уровню навыков просто не мог в ней участвовать. Чем, собственно, освободить высококвалифицированных от исполнения упростившихся задач и использовать их там, где задачи сильно сложнее. Причём, настолько сложнее, что до появления ценных абстракций эти задачи просто нереально было решить за разумные сроки.
Часто говорят, будто языки, отличные от низкоуровневых, побуждают программиста писать хреново. На самом деле, тот, кто пишет хреновую программу на Java, если бы стал вдруг писать на С++, написал бы такой адский трэш, что лучше бы уж вообще ничего не писал. На более удобных языках результат будет лучше и у хреновых программистов и у отличных. Просто результаты труда хренового программиста на менее удобном языке вообще бы практически отсутствовали. И эту работу, как легко догадаться, пришлось бы делать отличному. Что, как легко догадаться, не дало бы ему сделать какую-то другую работу. До последнего, впрочем, легко догадаться, по ходу, не всем.
Разумные сроки, обратно, упираются в цену вопроса. При решении задач «в лоб», скорость появления следующего приложения возрастает не особенно сильно. Да, программист часть решений теперь уже помнит, но всё равно вынужден их набирать заново. Ну или копипастить из прежнего кода и вдумчиво модифицировать. В обоих вариантах попутно каждый раз восстанавливая в памяти все детали и нюансы. Внесение в язык процедур позволяет часть уже решённых задач перенести в новый код не копипастом, а библиотекой. И вызывать его быстро и коротко просто по ссылке-процедуре. Каждая следующая абстрактная концепция делает всё бо́льшую часть ранее написанного кода переносимой. Объекты позволяют перенести не только некий блок кода целиком, но и вклиниваться в его составные части. Внутренние объекты и функции как объекты первого рода позволяют вклинивание сделать ощутимо более лаконичным и гибким. Аспекты позволяют вклиниться сразу во множество функций, а не в каждую по отдельности и так далее. В результате внедрения этих концепций квалифицированный программист сокращает время написания каждого следующего приложения в десятки раз. И да, неквалифицированный сам не сокращает, однако и он пишет в десятки раз быстрее — пользуясь наработками квалифицированного. Падение стоимости разработки — астрономическое. При этом ещё и надёжность растёт. И даже, как ни странно, в среднем растёт скорость работы программы. Либо же, как альтернатива, её функциональность.
Далее. Большой объём кода при ограниченном времени разработки не позволяет произвести полную оптимизацию каждого его фрагмента. Поэтому при низкоуровневом подходе, хоть и существует возможность лучшей оптимизации, но возможность эта — гипотетическая. В среднем будет использован не тот идеально оптимизированный на низком уровне вариант, мыслящийся носителям идеи Безграничной Квалификации Пряморуких, а тот, который можно реализовать быстрее. Кроме того, разработчик не имеет возможности проводить по каждому чиху полноценные исследования, на это есть время только у того, кто специально занимается данной конкретной проблемой долгое время. По этим причинам низкоуровневое решение в среднем будет работать не только менее стабильно, чем высокоуровневое, но ещё и медленнее. Оптимальный вариант с некоторыми вызванными высоким уровнем накладными задержками скорее всего будет всё равно более быстрым, чем сделанный навскидку какой-то иной вариант. Ну а если один из таких фрагментов придётся на «бутылочное горлышко», то уже пофиг, что какие-то другие места были мастерски соптимизированны — всё в сумме работать всё равно будет медленно.
Что, к слову, регулярно являет себя миру. Вот, например, нужен был нам картографический сервер. Нашли два. Один на Java, второй — на С++. Ну все ж знают, что Java тормозит. Наверняка С++-ный будет быстрее. Хрен бы там. Он мало, что умел меньше явовского, так ещё и то, что умел, делал раз в пять медленнее. Казалось бы, быстрый С++, медленная Java. Ан нет. Всё строго наоборот. Все потенциальные накладные расходы Явы и все возможные оптимизации С на низком уровне привели совсем к иному результату, нежели обычно ожидается. А всё почему? Потому что JIT хоть и даёт не самый мощный результат из возможных, однако программисты в среднем дают ещё менее мощный результат, пытаясь вручную что-то там с памятью и регистрами соптимизировать в масштабном проекте.
То количество кода, из которого в совокупности состоит даже не очень большое современное приложение, ни один человек на Земле не сможет удержать в памяти. Ни один человек не сможет даже запомнить все нюансы и детали. Группа людей, не имея возможности оформить код в относительно выскоуровневые модули, не сможет банально рассказать друг другу, каким образом интегрировать их в единое целое. В результате гипотетически оптимальное приложение просто не будет физически существовать. В теории оно очень быстро работает, на практике оно не работает вообще — его нет.
Те программы, которые мы сегодня видим и регулярно используем, в гипотетическом мире одних только низкоуровневых языков просто не появились бы. Вместо Ворда с Ин Дизайна всё бы сейчас набиралось и версталось в досовском редакторе текстов. А Лексикон казался бы вершиной развития технологий. Стоимость разработки бухгалтерской программы для мелкого предприятия исчислялась бы в десятках миллионов долларов. О да, эта программа гипотетически «летала бы» на 286-м. А что толку? Кто бы за это дело заплатил? Кто бы выждал десять лет до появления результата?
Низкий уровень позволяет достичь выдающейся производительности приложения в теории. Высокий — физического существования этого приложения.
Рост уровня языков — неизбежен. Неизбежно и оформление кода в высокоуровневые абстракции, которые своим существованием замедляют работу синтетических тестов, но хотя бы делают возможным написание приложений с огромной функциональностью. Неизбежно и упрощение низкоуровневых концепции за ради возможности привнесения высокоуровневых. Это не бага, это — фича. Так и должно быть и слава богу, что так есть.
так когда же, наконец, всё сведется к одной кнопке "сделать 3.14здато"?
Re: Ответ на вашу запись...
Re: Ответ на вашу запись...
Вообще говоря, денутся. Рано или поздно будет реализовано и оформлено практически полное множество низкуровневых алгоритмов, после чего низкий уровень, собственно, останется весь там: в низкоуровневых алгоритмах. Ну, собственно, на ассемблере сейчас вряд ли пишут больше одной сотой процента всего разрабатываемого в мире софта. А лет сорок назад всё было совсем не так.
> Пишет - а как будет работать написанное, не задумывается.
Тут как бы задумываться в большинстве случаев и не надо. Чтобы, например, понять, отчего ArrayList быстрее обращается по индексу, чем LinkedList какие-то детали организации памяти знать не нужно. Память вполне можно рассмотреть как некую абстракцию с заданными свойствами, но неизвестной организацией.
> Откуда возьмутся специалисты высокого уровня, если у них на том месте, где должно быть понимание уровня низкого - дыра?
Специалисты высокого уровня могут заниматься в том числе высоким уровнем. Собственно, пилот самолёта вряд ли умеет его чинить. И уж точно не сможет собрать самолёт с нуля.
Далее, так код в Яве более поддерживаемый, то оказывается, что на сложных алгоритмах написанных на Си изза большей сложности отслеживать код, совершаются высокоуровневые ошибки в алгоритмах намного более замедляющие программу.
Это все последствия как раз стоимости разработки, в Хотспот вложено столько сил высокоrласных специалистов, что очень дорого его повторить в конкретном приложении.
Ну а так, действительно основной плюс Ява приложений это как раз поддержка. Не стоимость даже написания, она не так важна, а именно стоимость поддержки.
Типовое приложение как правило пишут по довольно нечетким критериям и с заточкой на постоянную поддержку и добавление новых фич, та самая гибкость поддержки. И вот Ява тут оказывается намного впереди Си, поэтому даже приложения с очень строгими требованиями по быстройдействия очень часто ведут на Яве.
Тут стоит еще раз подчеркнуть, что с точки зрения бизнеса, быстродействие програмы это даже для перфоманс приложений фактор менее значимый, чем гибкость и поддерживаемость приложений. Для не перфоманс приложений, разница еще разительнее.
631882
Re: 631882
1. Нет сборщика мусора по-умолчанию. Поэтому, даже если каким-то чудом написать свой, сравнимый по эффективности с явовским, то в сторонних библиотеках всё равно везде будут торчать уши прямого управления памятью. То бишь, постоянно надо вникать, каким образом и когда удалять всё подряд, и так далее.
2. Нет строк по умолчанию. То, что они потом появились в STL, ни фига не спасло — всё равно у всех кругом свои собственные. Отсюда одно из самых распространённых подмножеств операций выносит целую кучу проблем с конвертациями и несовместимостью. char*, само собой, — адский ад.
3. Нет внутренних классов, поэтому нереально даже сымитировать замыкания. Есть указатели на функции, а что толку-то?
4. Множественное наследование требует ключевых слов там, куда их обычно внести уже невозможно — в объектах из библиотек.
5. Разрешены невиртуальные методы. См. вторую половину п. 4.
6. Три сущности — объекты-значения, ссылки и указатели. См. «постоянная несовместимость».
7. Нет интроспекции вообще. Поэтому даже не удивительно, что нет аннотаций — один хрен никаких мега-обобщений не получится.
8. Синтаксис в ряде аспектов адский. Поэтому даже к сигнатуре функций зачастую надо писать комментарии, а то никто не разберёт, какого типа значения туда предполагается передавать и что с ними потом может произойти.
9. В сообществе нет общепринятых соглашений об именовании. В результате всё везде названо разными способами.
Я бы только отметил, что "оптимальность" обучно подразумевает не "бескомпромиссно-максимальную производительность",
а некоторый максимум по совокупности критериев (типа производительность+реализуемость+гибкост
Иногда даже не совсем максимум - ибо не факт, что изначально удаётся определить полный набор критериев, и этот набор
не изменится. И тогда гибкость и эффективность в поддержке оказываются важнее всего.
А в приложениях сприоритетом производительности умыне люди давно стараются выделять критические участки,
которые можно сделать хоть на чём - хоть на ассемблере.
Э, устарело. Есть ещё один вариант.
http://lambda-the-ultimate.org/node/2551
Re: Ответ на вашу запись...
Re: это что щас так модно, что если без ошибок
> Для приведения оного беспредела к сколь либо приемлемому состоянию программист для начала вводит фабрики. Потом, осознав, что объекты всё равно приходится вовремя удалять, делает подсчёт ссылок....однако в среднем он написал не его, а что-то совсем другое, несравнимое.
Вот в таких пассажах я вижу желание думать, что Си-программисты в среднем тупее, чем высокоуровневые программисты. Хочу заметить, что С/C++ - кодеры не хуже Java-программистов используют то обстоятельство, что памяти сейчас много. Например, мало кто пишет собственные сборщики мусора. Подавляющее большинство разработчиков опирается на какую-либо версию библиотеки промышленного качества. Да что там, даже delete someObject; в нынешнем коде нужно будет поискать. Также в полный рост используются пулы объектов и аллокация на стеке (нулевая стоимость)
> Рост уровня языков — неизбежен... Неизбежно и упрощение низкоуровневых концепции за ради возможности привнесения высокоуровневых. Это не бага, это — фича.
С удовольствием бы перешёл на какой-нибудь современный высокоуровневый язык. Но проблема в том, что разработчики современных языков повёрнуты жопой к разработчикам аппаратуры. Скопировать буфер байтов с одного места в другое без разных маршаллингов просто невозможно. Сделать какое-нибудь преобразование из потока байт в структуру состоящую из примитивных типов - жопа. А уж если собирать строку - то обязательно познакомишься с устройством менеджера памяти. Во многом такой идиотизм насаждается как раз высокоуровневыми идеями типа "память - абстрактное устройство", "байтов нету, есть только объекты". Конечно, когда программируешь только компьютеры, то на это наплевать. А когда создаешь собственный прибор/станок/установку, подключаемый к компьютеру то в большинстве случаев единственный вменяемый язык для этого - Си. И сейчас подключение собственного прибора к компьютеру дороже, чем 10-15 лет назад. Вот такой прогресс.
Очень тронуло, когда нашел в C# класс Buffer. Его устройство признает право за программистом копировать байты как байты и делать из них примитивные типы без промежуточных мегабезопасных, супероптимальных маршаллингов. Это, блеать, прорыв в мозгах разработчиков высокоуровневых языков.
Как программиста на высокоуровневом языке Delphi, меня забавляют эти проблемы. Как раз с аппаратурой работаю, да. И никаких {}&&||!=-> и прочих малопонятных конструкций ;-)
Holywar mode off :-)))
Кстати говоря, манера измерять время при помощи циклов сыграла в свое время дурную шутку с пользователями программ, написанных криворукими программистами. Процессоры AMD, начиная с К5, умели распознавать простые циклы с односложными действиями, и выполнять их за существенно меньшее время. Но в программе-то этого не ожидали... Отсюда идет миф о "глючных" процессорах AMD.
Вместо Ворда с Ин Дизайна всё бы сейчас набиралось и версталось в досовском редакторе текстов
Тут двоякая проблема. К сожалению, 98% пользователей Ворда пользоваться им не умеют. Потому, смотря на результат работы таких пользователей, появляются мысли, что даже plain text им в руки давать опасно.
Ах, да. К вопросу об оптимальности. Программы пишутся в 99,99% случаев не для того, чтобы потешить самолюбие программиста, а для того, чтобы с их помощью решить какие-то задачи. Вот исходя из этого и надо рассматривать оптимальность программы. И тут мы сразу сталкиваемся с тем фактом, что пресловутая оптимальность далеко не только от технического качества программы зависит; в ряде случаев она может зависеть, например, от решения ее создателями коррупционных вопросов, от инерционности мышления и т.п. факторов, которые, казалось бы, к программированию не имеют вообще никакого отношения.
Re: Ответ на вашу запись...
Что-то мне подсказывает, что досовским редактором они бы не умели пользоваться ещё сильнее.
Возможно поэтому труд рабочих(и инженеров) в СССР был "менее эффективным" - он был также эффективным, но за счет создания дополнительной прочности и устранения тех 10% ошибок в целом получалось медленнее
Re: Ответ на вашу запись...
ВКП(б)VB(A) больше не полезу.[ушел жечь "Си для чайников"]
Но нет плохих и хороших языков, есть цели и инструменты. Старичка Си, видимо, следует оставить для задач его уровня, т.е. сейчас это микроконтроллеры и софт, работающий напрямую с железом. Не знаю, будут ли когда-нибудь слова Realtime и Java стоять вместе без частицы "не" =)
Re: Ответ на вашу запись...
Например, как все известно, нет плохих фотоаппаратов, есть плохие фотографы. Настоящий мастер наверняка на и мобилку снимет как на Canon Mark II.
> Не знаю, будут ли когда-нибудь слова Realtime и Java стоять вместе без частицы "не" =)
Они уже много лет кряду так стоя́т.
Толковый программист нынче в основном админ, т.е. просто активно использует уже наработанное и искусство тут в толковом разделении задачи на части и грамотном разнесении частей по исполнителям (процам, серверам, клиентам, кластерам и т.д.), в придумывании простой и эффективной связки (тут, возможно, потребуется что-то накодить) между частями и, наконец, в поиске толкового уже наработанного и отлаженного кем-то кода для своей задачи. Проблема по-моему как раз в том, что большинство из тех, кто называет себя программистом, на мой взгляд, не умеет ни на подзадачи делить, ни "связки" придумывать, ни искать толковый код. Для того же поиска кода надо и не лениться, и понимать что из себя представляет толковый код и, самое главное, руководствоваться при поиске и выборе принципом "разделяй и властвуй", а не "мне бы что-нибудь одно для всего сразу и чтоб оно само". Последний принцип в моде всегда, так как каждый (я в том числе) хочет иметь максимум отдачи при минимуме усилий, но и меру-то тоже надо знать. :)
В отношении заимствования можно заметить следующее. В силу исторических причин, толкового наработанного и отлаженного кода на Си по-моему просто немеряно. Собственно, в качестве примера, какой смысл ради grep'а текстового файла по словосочетанию поднимать целую ява-машину со сборщиком мусора и писать мегаООП-проект? А на Си есть маленькая, простая и давно отлаженная программка (man grep). Если же мы говорим о каких-то новых областях, где наработанного кода нет или мало, то по-моему ява/perl/php и прочее "высокоуровневое" хорошо для прототипирования, а уже продуманную таким образом реализацию нужно делать на том же Си мозгами и руками толковых, настоящих программистов, а не, простите, "компонентодрочеров" (или "объекто-", на ваш вкус). И опять же не забывая про "разделяй и властвуй". И тут мы, кстати, спотыкаемся о проприентарную модель разработки, благодаря которой компании тратят средства на "изобретение колеса" и на огораживание этого процесса лицензиями и патентами. Т.е. вместо однократных затрат кем-то (отдельно или консорциумом каким) на разработку, отладку ПО и предоставлении этого ПО в совместное пользование, компании раз за разом пытаются снизить затраты на "изобретение" этого ПО. :)
Вообще же, насколько я знаю и в чём с автором согласен, ООП-языки и тем более Ява были придуманы совсем не для ускорения работы конечного продукта - они были придуманы для снижения стоимости разработки. Бизнесу нужно снижать издержки на производство, поэтому и появляются дешёвые, хоть и неэффективные решения. Это не хорошо и не плохо, это просто так есть когда приходится бороться за ресурсы (прибыль). С этой точки зрения гонка за эффективностью будет уместна только тогда, когда эффективность является решающим конкурентным преимуществом. Как показывает практика, на деле мы имеем своего рода картельный сговор: снижение затрат на разработку ПО (за счёт снижения его эффективности) выгодно и производителю ПО, и производителю аппаратных решений, так как заставляет последнего, грубо говоря, наращивать гигагерцы и предлагать всё более "новое", всё невиданнее "быстрое" и т.д.
С другой стороны, былое вылизывание кода, скорее всего, было обсуловлено и слабостью тогдашнего железа, благодаря чему неффективный код некрасиво выпячивался на поверхность, позоря автора. В нынешнюю же эпоху проприетарного ПО и более мощного железа можно писать всякий хлам и скорее всего никто ничего не заметит.
Последствия всего этого можно выписывать и обсуждать долго, поэтому здесь остановлюсь. :)
Re: Ответ на вашу запись...
Я объясню: программа на С, будь она сто раз отлаженной, запустится только под той ОС, под которую её собрали. Если такое устраивает, то всегда лучше использовать готовый вариант. В иных случаях, приходится что-то там писать. Поднятие же ява-машины сейчас уже абсолютно пофиг, поскольку ни по скорости, ни по потреблению памяти незаметно.
> Если же мы говорим о каких-то новых областях, где наработанного кода нет или мало, то по-моему ява/perl/php и прочее "высокоуровневое" хорошо для прототипирования, а уже продуманную таким образом реализацию нужно делать на том же Си мозгами
На С уйдёт лет эдак сто, где на яве ушло бы меньше года.
> Вообще же, насколько я знаю и в чём с автором согласен, ООП-языки и тем более Ява были придуманы совсем не для ускорения работы конечного продукта - они были придуманы для снижения стоимости разработки.
Снижение стоимости разработки и есть прямая причина повышения скорости работы. Если за пять тысяч баксов пишется программа на яве, то работающая хотя бы с той же скоростью и стабильностью программа на С стоила бы уже пятьдесят тысяч. А за пять тысяч оно будет в разы медленнее работать, поскольку этих денег хватит чисто на оплату непосредственно набирания кода, без проектирования, оптимизации и т.п.
Вы забыли умножить стоимость проца на количество проданных экземпляров программы. Или же нужно сравнивать стоимость разработки более эффективной программы со стоимостью разработки более мощного проца и производства всего его тиража.
Описанный вами подход действительно капиталистический: при выборе программы пользователь оценивает в первую очередь её функционал и цену, а во вторую - эффективность. И он, соответственно, скорее купит программу, которая на 10$ дешевле (потому что 2000$ зарплата программиста, сэкономлено 2 месяца работы, и продано 400 экземпляров программы) и потом процессор за 300$, чем более дорогую программу, которая без апгрейда процессора покажет те же характеристики. Оптимизировать программы выгоднее глобально, но невыгодно финансово (такой вот парадокс). Как, скажем, невыгодно делать качественную и полезную зубную пасту или натуральную колбасу - покупатель эти характеристики, хоть и считает важными, но не может оценить при выборе товара, поэтому и производитель делает упор на вкус (достигается химическими вкусовыми добавками), красоту обёртки и рекламный слоган, говорящий о натуральности продукта.
Re: Ответ на вашу запись...
Это зависит от того, сколько экземпляров в принципе рассчитывают продать и кому. Если приложение под заказ — экземпляр вообще говоря будет один. Если оно для узкого круга, то количество экземпляров будет измеряться десятками. Для коробочных приложений может быть и миллион экземпляров. Но все три варианта существенно различаются по принципам разработки. И, соответственно, затраты тоже будут изрядно варьировать. В приложении под заказ ряд вещей будет делаться чисто потому, что заказчик так захотел — не взирая на сложность реализации. В коробочном приложении такие детали можно смело взять и выкинуть. Соответственно, тормоза будут совсем уже не те, что в первом варианте.
> Или же нужно сравнивать стоимость разработки более эффективной программы со стоимостью разработки более мощного проца и производства всего его тиража.
На одном и том же проце запускается не одна единственная программа, а миллионы. Если мы это дело сравниваем, то сравнивать надо разработку более мощного проца с разработкой миллионов более эффективных программ. И тут стоимость будет сильно в пользу разработки именно проца.
> Оптимизировать программы выгоднее глобально, но невыгодно финансово (такой вот парадокс).
Оптимизировать их глобально ровно так же невыгодно. Если десять процентов прироста в скорости требуют удвоения времени разработки, то есть ли в мире деньги, нет ли их, один хрен нужно где-то взять либо вдвое (а реально — втрое) больше программистов, либо написать вдвое меньше софта. Легко догадаться, что чувака, вынужденного что-то считать на калькуляторе ввиду отсутствия спец-приложения под это дело, совершенно не греет мысль, что благодаря этому у кого-то теперь в программе на десять процентов быстрее стало всё считаться.
Если разработка нового проца требует десять тысяч человеко-часов, такое равно по затратам в естественных показателях, месяцу работы шестидесяти двух программистов. Легко догадаться, что при наличии миллионов программистов, новый проц гораздо полезнее. Даже в человеко-часах.