Переучиватся на С++
Сносно знаю Си, но мне все вокруг говорят, что это отстой и нужно обязательно и срочно переучиватся на С++ подход, а то потом, в будущем когда будешь искать работу, Си в чистом виде никому не нужно.
Че скажете? Так оно и есть или не совсем?
А то меня этот ООП не радует :)
Не нужно погружать в зубрежку. Плавно перейдешь...По немногу, в процессе.
А то меня этот ООП не радует :)[/QUOTE]
И на С++ можно без ООП писать :) Только оно надо? Знание сишки никогда никому не мешали. Так же как знание асма, паскаля, басика и т.д. Если владеешь более чем одним языком, в каждом из которых используется разный подход - тем более ценен ты как разработчик.
это про ООП? Ну так ООП можно и в C, если тебе не нравиться ключевое слово class. Только когда этого ООП много (скажем, штук двадцать типов, и пяток уровней наследования), то довольно неудобно без поддержки со стороны языка.
С - не ООП, это простейшие структуры и не более того.
Принципы ООП - инкапсуляция, полиморфизм, наследование - разве хоть один из них есть на С? Без этих принципов это не ООП, а просто структуры. Ну может быть, с методами.
P. S. ООП рулит, жаль что некоторые (например, автор этой темы) не понимают этого.
Сносно знаю Си, но мне все вокруг говорят, что это отстой и нужно обязательно и срочно переучиватся на С++ подход, а то потом, в будущем когда будешь искать работу, Си в чистом виде никому не нужно.
Че скажете? Так оно и есть или не совсем?
А то меня этот ООП не радует :)[/QUOTE]
Насчет ООП - очень жаль, что он тебя не радует. Често сказать, когда-то давно я прогал на Pascal и впервые увидел товарища, прогающего на С (или это был уже С++...), и не понял этого языка. Он мне казался таким уродливым, и я подумал, что никогда не сяду за него.
Прошло года 3, я все-таки купил ради интереса книжку по С++. И ТОГДА Я ПОНЯЛ, что это рулз.
ООП - великая вещь. Возьми хотя бы перегрузку операторов - ты сможешь складывать и перемножать матрицы и вообще любые объекты! А чего стоит наследование и особенно виртуальные функции? Это незаменимое средство повторного использования кода без его переписывания.
[QUOTE=Lucky_Strike]нужно обязательно и срочно переучиватся на С++ подход[/QUOTE]
Это делают только для того, чтобы пользоваться ООП.
Принципы ООП - инкапсуляция, полиморфизм, наследование - разве хоть один из них есть на С? Без этих принципов это не ООП, а просто структуры. Ну может быть, с методами.
P. S. ООП рулит, жаль что некоторые (например, автор этой темы) не понимают этого.[/QUOTE]
На самом деле понятие ООП весьма расплывчато. Тот же С++, к примеру, не обладает инкапсуляцией в полной мере (см. принцип Парнаса), приходится добиваться этого специальными конструкциями (интерфейс+фабрика или pImpl).
чтож, уболтали :)
Это делают только для того, чтобы пользоваться ООП.[/QUOTE]
c = multiply_matrix( a, b );
А перегрузка ведь, её как бы тоже надо определять. Так же как и функцию multiply_matrix. Только в случае отдельной функции код яснее
Только в случае отдельной функции код яснее[/QUOTE]
Странно, мне всегда казалось более естественным УМНОЖЕНИЕ писать как УМНОЖЕНИЕ.
Другой пример:
C = (A*B)*C*(D+(E*F))
Pascal:
C := multiply_matrix(multiply_matrix(multiply_matrix(A,(B,C)),add_matrix(D,multiply_matrix(E,F)))
Сколько времени потратишь на то, чтобы найти ошибку? :)
Вот потому-то я за С++ и засел.
И пример `C = (A*B)*C*(D+(E*F))', это неплохо демонстрирует:
Умножать матрицы так не стоит ни в C, ни в C++, это тормозно. Лучше написать отдельную функцию, которая будет умножать 3 матрицы, 4 или, даже, произвольное число (ellipsis-то на что?). Идея в том, что вместо того, чтобы по десять раз грузить одни и те же данные в регистры sse, а потом сохранять в память (с сопутствующими транспонированиями/перетасовками), обойтись пятью, а то и одной загрузкой и одной выгрузкой. При этом возможности по оптимизации тут безумные: оптимизация кеш-попаданий, угадывание процессором условных переходов... А с размером конвейера в P4 это очень сильно. Замечу что всякие матричные функции, далеко не всегда имеет смысл оформлять как inline, и чем чаще они нужны, тем больше поводов использовать их как extern функции. А это значит что компилятор не сможет обойтись без динамического выделения памяти и лишних копирований матриц. И процентов 10-20 производительности (а то и 100-200) коту под хвост.
И всё это, только из-за того, что у программера появился соблазн определить operator* для матриц, а сделав это, он уже не представляет себе _что_же_ он пишет.
Что-то тебя не туда понесло...
При чем тут ООП и оптимизация?
а что "при чём"?
Понимаешь, когда я пишу irc бота на лиспе, мне плевать, что процесс лиспа будет в оперативке занимать метров двадцать-тридцать. И забив на них, я выбираю тот язык, который мне удобнее всех остальных для работы с irc, http, html, sql, а также для других задач, которые должны выполняться ботом. И я навешиваю на этого бота, десяток тяжеловесных библиотек начиная с cl-sql и заканчивая cl-prolog'ом. И получаю монстра. Зато я получаю его за три дня. И если через полгода, в связи с изменившейся ситуацией выясниться что были допущены ужасные ошибки при "проектировании", то я за два часа успею и разобраться в своём коде и переделать его так чтобы добавить в него всё что мне ещё понадобилось.
То есть я себе отдаю полный отчёт в том, чем я жертвую, и ради чего жертвую.
Но когда мы говорим о C++, то если мы забиваем на скорость работы программы и её размер, то встаёт вопрос, а на хрена нам вообще сдался этот C++? С его указателями, memory leakage и прочими проблемами? Может лучше взять java и не выпендриваться? Или perl/python?
<skip>
Но когда мы говорим о C++, то если мы забиваем на скорость работы программы и её размер, то встаёт вопрос, а на хрена нам вообще сдался этот C++? С его указателями, memory leakage и прочими проблемами? Может лучше взять java и не выпендриваться? Или perl/python?
[/QUOTE]
Нифига не понял из твоего монолога. Что ты хотел выразить?
Я правильно понял, что для того чтобы писать на С++ "не забивая на скорость работы программыи её размер", надо отказаться от ООП концепции этого языка и хачить в стиле С ?
В таком случае фигню говоришь.
Что касается проблем "с его указателями", то при правильном подходе к стилистике, проблем не будет, как и многих других проблем.
Лучше написать отдельную функцию, которая будет умножать 3 матрицы, 4 или, даже, произвольное число... При этом возможности по оптимизации тут безумные...[/QUOTE]
Пиши критические к скорости участки кода на ассемблере, в чем проблема-то? Оператор умножения можно без проблем написать на ассемблере и вызывать его уже из С-кода.
А насчет использования разного рода регистров, тебе их вряд ли хватит, чтобы перемножить хотя бы 2 матрицы 5х5.
[QUOTE=foo]...у программера появился соблазн определить operator* для матриц, а сделав это, он уже не представляет себе _что_же_ он пишет.[/QUOTE]
Не понял.
Как показывает практика существенная оптимизация происходит именно на более высоких уровнях - сам алгоритм и его реализация.
Даже заоптимизированная до невозможного функция, вызываемая несколько миллионов раз, сведет на нет всю оптимизацию.
Так же примечателен неправильный подход к процессу оптимизации. Какой смысл думать о загрузке регистров, если нет ещё реализации самого алгоритма. Так и хочется спросить: перемножение матриц - это самая тормознутая часть в твоей программе? Нет? Так на кой хрен тогда тратить на это время?
Правильный подход - это реализовать для начала просто рабочий алгоритм. Может, подобное вычисление и не нужно вовсе.
Потом подумать над эффективностью этого алгоритма. Если теоретически алгоритм может иметь сложность O(n), а твой алгоритм O(n^3), то не стоит хвататься за оптимизацию участков кода его реализации. При выборе алгоритма как раз полезен подход ООП, т.к. он несколько снижает затраты времени на реализацию. При правильном подходе реализация напоминает абстрактное описание алгоритма и может даже реализовываться сверху вниз (см.TDD), т.е. сначала описываем более общие части алгоритма в терминах сущностей и операций над ними, а потом можем спуститься до реализации самих сущностей и операций.
Допустим алгоритм принят и соотв-но уже реализован. Допустим реализация тоже имеет право на жизнь, но оптимальна ли?
Вот теперь происходит процесс профайлинга, где выясняются тонкие места. И если даже у меня матрицы перемножаются неоптимально быстро, но есть места более вопиющие, я сначала возьмусь за них. В процессе может оказаться, что перемножение и вовсе не надо, тогда для чего было тратить время на это с самого начала? Или окажется, что матрицы перемножаются медленно, но один раз, тогда я лучше переключусь на то, что выполняется чаще.
В результате в большинстве случаев оказывается, что низкоуровневая оптимизация ускоряет те участки, которые не критичны в основной массе, а время на подобную оптимизацию уходит много и приводит к нечитабельности кода, которая очень важна особенно на начальных этапах выбора и реализации алгоритма.
Еще одно заблуждение, что сокрытие реализации (инкапсуляция) вредна для пользователя и что он даже "не представляет себе, что же он пишет". В чем заблуждение нужно объяснять?
Я правильно понял, что для того чтобы писать на С++ "не забивая на скорость работы программыи её размер", надо отказаться от ООП концепции этого языка и хачить в стиле С ?
Не совсем. Уточняю. Использование оператора умножения матриц, совместимо с оптимизацией только тогда, когда наша программа делает это умножение достаточно редко.
угу, но _зачем_ мы будем требовать от программеров большей квалификации? _Ради чего_? Более того, ты изучал когда-нибудь bug-lists всяких проектов? Заглядывал в описание багов и патчи для исправления, чтобы понять какую ошибку допустил программер? Проблемы с указателями, неинициализированными переменными достаточно распространены, и никто не застрахован от этих ошибок. До тех пор, пока язык не снимет необходимость за этим следить.
А насчет использования разного рода регистров, тебе их вряд ли хватит, чтобы перемножить хотя бы 2 матрицы 5х5.
я плохо объяснил почему оптимизация одного только оператора умножения не даст хорошей степени оптимизации?
Кроме того, разве я говорил, что надо загружать все матрицы в регистры _одновременно_? Я говорил о количестве загрузок/выгрузок, и количестве копирований выделений памяти сопровождающих вызовы operator*.
Делать надо вот что: когда было замечено, что, возможно, оптимизация выражения A*B*C*D, возможно, имеет смысл (замечу, изучив свой основной инструмент -- компилятор, для того чтобы заметить, надо просто обратить внимание), надо расписать формулу для (i,j) элемента матрицы A*B*C*D, и прикинуть, а нельзя ли считать по этой формуле быстрее, чем тупо выполняя три операции умножения матриц. И если да, то везде, где происходит несколько последовательных умножений матрицы писать не операторы умножения, а вызов функции mult_matrices. А, вот, оптимальную реализацию этой функции, стоит оставить на "после профайлинга".
[...]
Так же примечателен неправильный подход к процессу оптимизации. Какой смысл думать о загрузке регистров, если нет ещё реализации самого алгоритма. Так и хочется спросить: перемножение матриц - это самая тормознутая часть в твоей программе? Нет? Так на кой хрен тогда тратить на это время?
[...]
А это типичная ошибка среднего программиста, проистекающая из отсутствия опыта оптимизации достаточно большого проекта.
Потому что, когда реализация алгоритма будет готова, вполне вероятно может возникнуть ситуация, когда без переписывания этого алгоритма оптимизация даст 10% прироста в скорости. Знаешь поговорку "семь раз отмерь, один отрежь". Лучше сидеть полгода проектируя программу, а потом написать её за год, чем написать эту программу за два года, а потом ещё полгода её переписывать.
Вот прикинь, для программы написана библиотека, которая выполняет сложные вычисления и позволяет отвлечься от реализации при написании собственно приложения. Написано это приложение. И в процессе анализа производительности, выясняется, что возможно повысить скорость работы программы процентов эдак на 200%, но для этого необходимо изменение api библиотеки. Красиво? Не лучше ли, не столь абстрагироваться от реализации библиотеки, и предсказать результат раньше, в процессе написания приложения, просто заметив насколько api не соответствует задаче?
если ты говоришь о, примере к которому мы прицепились -- о матричной арифметике, -- то объясни. Мне непонятно.
И последнее, я сижу в линухе, на opensource софте, в сорцы которого я регулярно заглядываю. у меня иногда возникают мысли о проведении оптимизации той или иной программы. Логично предположить, что эти мысли возникают из-за того, что скорость работы программы/использование ею оперативной памяти, не соответствует моим ожиданиям. И я не ленюсь посмотреть за счёт чего можно программу оптимизировать. Даже не ради оптимизации, а просто чтобы убедиться в том, что мои ожидания меня не обманывают и мне просто любопытно, как программы работают. Так вот, несмотря на то, что софта на C в системе больше чем софта на C++, с мыслями об оптимизации я чаще разглядываю код C++.
я плохо объяснил почему оптимизация одного только оператора умножения не даст хорошей степени оптимизации?
[/QUOTE]
Именно. Не думаю, что программа только перемножает матрицы, а о какой тогда степени оптимизации вообще можно говорить.
Чисто в общем оптимизации не существует, а тем более в процентном выражении.
Если я проеду 5 км на автобусе на сколько процентов я съоптимизирую свой путь?
[QUOTE=foo]
угу, но _зачем_ мы будем требовать от программеров большей квалификации? _Ради чего_? Более того, ты изучал когда-нибудь bug-lists всяких проектов? Заглядывал в описание багов и патчи для исправления, чтобы понять какую ошибку допустил программер? Проблемы с указателями, неинициализированными переменными достаточно распространены, и никто не застрахован от этих ошибок. До тех пор, пока язык не снимет необходимость за этим следить.
[/QUOTE]
Значит у вас проблемы, как с квалификацией программистов, так и с культурой программирования. Для того чтобы не допускать (или снизить риск) подобных багов надо бы внедрить единую стилистику (pss), регулярно проводить codereview (особенно для низкоквалифицированных программистов), внедрить парное программирование для новичков, которых НАДО учить, и не плохо бы внедрить модульное тестирование, если слабо вообще перейти на TDD. Кроме того существуют регрессионные тесты, языковые механизмы избежания подобных проблем и т.д.
[QUOTE=foo]
Кроме того, разве я говорил, что надо загружать все матрицы в регистры _одновременно_? Я говорил о количестве загрузок/выгрузок, и количестве копирований выделений памяти сопровождающих вызовы operator*.
Делать надо вот что: когда было замечено, что, возможно, оптимизация выражения A*B*C*D, возможно, имеет смысл (замечу, изучив свой основной инструмент -- компилятор, для того чтобы заметить, надо просто обратить внимание), надо расписать формулу для (i,j) элемента матрицы A*B*C*D, и прикинуть, а нельзя ли считать по этой формуле быстрее, чем тупо выполняя три операции умножения матриц. И если да, то везде, где происходит несколько последовательных умножений матрицы писать не операторы умножения, а вызов функции mult_matrices. А, вот, оптимальную реализацию этой функции, стоит оставить на "после профайлинга".
[/QUOTE]
Ага вот ты и подходишь к оптимизации снизу. См. описанную выше ошибку начинающих/продолжающих.
[QUOTE=foo]
А это типичная ошибка среднего программиста, проистекающая из отсутствия опыта оптимизации достаточно большого проекта.
[/QUOTE]
гы... я вообще не программист...
Я 13-летний кУлХаЦкЕр из Усть-Урюпинска.
[QUOTE=foo]
Потому что, когда реализация алгоритма будет готова, вполне вероятно может возникнуть ситуация, когда без переписывания этого алгоритма оптимизация даст 10% прироста в скорости.
[/QUOTE]
Ну вообще-то 10% это достаточно много.
[QUOTE=foo]
Знаешь поговорку "семь раз отмерь, один отрежь". Лучше сидеть полгода проектируя программу, а потом написать её за год, чем написать эту программу за два года, а потом ещё полгода её переписывать.
[/QUOTE]
Только вот большинство гуру как от программирования, так и от менеджмента говорят обратное (и я с ними солидарен): проектирование и разработка - процессы итерационные, и не следует засиживаться за проектированием, а тем более полгода, все равно всех нюансов до реализации не отыскать.
Ты про полгода проектирования серьезно? Как вы вообще выживаете?
[QUOTE=foo]
Вот прикинь, для программы написана библиотека, которая выполняет сложные вычисления и позволяет отвлечься от реализации при написании собственно приложения. Написано это приложение. И в процессе анализа производительности, выясняется, что возможно повысить скорость работы программы процентов эдак на 200%, но для этого необходимо изменение api библиотеки.
Красиво? Не лучше ли, не столь абстрагироваться от реализации библиотеки, и предсказать результат раньше, в процессе написания приложения, просто заметив насколько api не соответствует задаче?
[/QUOTE]
В том то и проблема, что сначала напроектировали, потом реализовали и столкнулись с проблемой. Если бы проектирование перемежалось с реализацией, применением, тестированием, анализом и рефакторингом, то такой бы проблемы не встало, т.к. она бы была решена в процессе.
А так, сколько API не проектируй все равно найдется заковырка, которая проявится только при попытке реализации.
[QUOTE=foo]
если ты говоришь о, примере к которому мы прицепились -- о матричной арифметике, -- то объясни. Мне непонятно.
[/QUOTE]
Ну к примеру, командная работа, разделение труда, использование ранних наработок.
Мне не обязательно заостряться на умножении матриц, т.к. это зона ответственности другого человека. Я сосредотачиваюсь на своей задаче и довожу её до рабочего состояния.
Только в рабочем состоянии я могу судить об производительности. Если после профайлинга выясняется, что слабое место в реализации самого умножения, то мы садимся вместе (если надо) и рещаем задачу по оптимизации.
Другой вариант, мультиплатформенность. К примеру, мы пишем под пять-шесть различных платформ (речь не о разных ОС, а о совершенно разном железе). Естествено, что для унификации процесса я буду стараться абстрагироваться от платформы, а это опять же достигается инкапсуляцией.
Вариант третий, незнакомая платформа или незнакомые механизмы. Опять же, я абстрагируюсь от незнакомых мне вещей, от вещей, где моя компетенция не столь велика, как у разработчика библиотеки.
[QUOTE=foo]
И последнее, я сижу в линухе, на opensource софте, в сорцы которого я регулярно заглядываю. у меня иногда возникают мысли о проведении оптимизации той или иной программы. Логично предположить, что эти мысли возникают из-за того, что скорость работы программы/использование ею оперативной памяти, не соответствует моим ожиданиям. И я не ленюсь посмотреть за счёт чего можно программу оптимизировать. Даже не ради оптимизации, а просто чтобы убедиться в том, что мои ожидания меня не обманывают и мне просто любопытно, как программы работают. Так вот, несмотря на то, что софта на C в системе больше чем софта на C++, с мыслями об оптимизации я чаще разглядываю код C++.[/QUOTE]
Заметь, ты не разу не упомянул о процессе профайлинга, т.е. ты просто методом научного тыка лезешь и оптимизируешь? :)
Одним из новых веяний в мире программирования является софт с динамическим контролем потребления ресурсов, особенно он применяется на серверах... Хватит теории. Речь о том что в данном стиле кодинга есть интересное положение об оптимизации - а именно что оптимизированный код должен вносится ПАРАЛЛЕЛЬНО старому коду с целью сравнения результатов, затрат и производительности при тестировании продукта. При этом уже в рантайме будет выбрана на выполнение именна та реализация, которая больше всего удовлетворяет текущим настройкам динамического контроля потребления. Старый код при этом спокойно лежит параллельно и никого не трогает, тем не менее сохраняя работоспособность на случай возникновения ошибки в более новых версиях. В этом случае при поддержке откатов операций программа выживет, выполнив старый, не заоптимизированный, но более надёжный в своей простоте код.
К чему я это пишу?
1) Снимает вопрос об оптимизации - её можно выполнить без ущерба на любой стадии при необходимости. И протестировать без проблем.
2) Подумайте сами, какой язык является более подходящим для реализации преймуществ данной архитектуры? При данном подходе С++ - именно то что нужно. Хотя бы потому что можно реализовать операторы приведения типов между различными реализациями одного и того же алгоритма, а также инкапсулировать каждую функцию в класс с поддержкой отката и сохранения начальных данных и состояния.
Просто хотелось сказать что для каждой задачи есть свой язык, и это не всегда С++. Тем не менее С++ является отличным способом построить СРЕДУ РЕШЕНИЯ ЗАДАЧИ, на нём не обязательно её РЕШАТЬ. А большинство(поправьте если я ошибся) програмных продуктов и являются СРЕДАМИ РЕШЕНИЯ разного рода задач. На мой взгляд, именно это и делает С++ наиболее приемлемым языком нашего времени, включая сопутствующие факторы, конечно. Например его эффективность, в случае правильного обращения, разумеется.
В принципе, любой язык будет крут при наличии знаний, опыта, и всего перечисленного у разработчика этого языка :) Язык существует в целях решения опредлённых задач. В случае С++ мы имеем все вышеперечисленные требования, а также самый широкий на сегодняшний день круг задач - создание сред(средств) решения задач. Поэтому сегодня я выбираю С++, несмотря на любые его недостатки, так как знания и опыт покроют их в любом языке. Учиться, учиться и... так далее :)
Чисто в общем оптимизации не существует, а тем более в процентном выражении.
Если я проеду 5 км на автобусе на сколько процентов я съоптимизирую свой путь?[/QUOTE]
ты пытаешься всегда смотреть на проблему в целом "инкапсулируясь" от деталей -- порочная практика.
[QUOTE=Green]Значит у вас проблемы, как с квалификацией программистов, так и с культурой программирования. Для того чтобы не допускать (или снизить риск) подобных багов надо бы внедрить единую стилистику (pss), регулярно проводить codereview (особенно для низкоквалифицированных программистов), внедрить парное программирование для новичков, которых НАДО учить, и не плохо бы внедрить модульное тестирование, если слабо вообще перейти на TDD. Кроме того существуют регрессионные тесты, языковые механизмы избежания подобных проблем и т.д.[/QUOTE]
Ух, вот с чем-с чем, а с этим, тьфу-тьфу-тьфу, проблем нету.
[QUOTE=Green]Ну вообще-то 10% это достаточно много.[/QUOTE]
для кода на C++? Который написан так как ты описываешь? Нет, в таком случае это много только тогда, когда задача, или её критические по производительности куски _вписались_ в ограничения накладываемые на программера ООП подходом и coding-style'ом конкретного проекта. В противном случае, можно надеятся и на 50-100%.
[QUOTE=Green]Только вот большинство гуру как от программирования, так и от менеджмента говорят обратное (и я с ними солидарен): проектирование и разработка - процессы итерационные, и не следует засиживаться за проектированием, а тем более полгода, все равно всех нюансов до реализации не отыскать.[/QUOTE]
Про "гуру" от менеджмента, у меня давно никаких сомнений не осталось.
[QUOTE=Green]Ты про полгода проектирования серьезно? Как вы вообще выживаете?[/QUOTE]
Живём на одном проекте. Который лет десять разрабатывался до момента когда его наконец стало возможно использовать не имея кластера на 64 проца. Наконец, PC доросли до задачи. Ещё пара проектов в процессе.
[QUOTE=Green]В том то и проблема, что сначала напроектировали, потом реализовали и столкнулись с проблемой. Если бы проектирование перемежалось с реализацией, применением, тестированием, анализом и рефакторингом, то такой бы проблемы не встало, т.к. она бы была решена в процессе.
А так, сколько API не проектируй все равно найдется заковырка, которая проявится только при попытке реализации.[/QUOTE]
угу. но я разве говорил, что проектировщику запрещается вешать на куски "скелета" программы/api "мясо"? Где программа будет тормозить после создания -- это очень предсказуемо, в большинстве ситуаций, не всегда ясно как лучше сделать, чтобы было лучше, но проработать возможные пути решения проблемы можно и нужно.
[QUOTE=Green]Ну к примеру, командная работа, разделение труда, использование ранних наработок.
Мне не обязательно заостряться на умножении матриц, т.к. это зона ответственности другого человека. Я сосредотачиваюсь на своей задаче и довожу её до рабочего состояния.
Только в рабочем состоянии я могу судить об производительности. Если после профайлинга выясняется, что слабое место в реализации самого умножения, то мы садимся вместе (если надо) и рещаем задачу по оптимизации.[/QUOTE]
Любая инкапсуляция обоснована, но она должна соответствовать сложности кода под нею прячущемуся. Если неинкасулированная матричная арифметика сбивает с толку программера, то пускай такой программер идёт работать дворником.
[QUOTE=Green]Другой вариант, мультиплатформенность. К примеру, мы пишем под пять-шесть различных платформ (речь не о разных ОС, а о совершенно разном железе). Естествено, что для унификации процесса я буду стараться абстрагироваться от платформы, а это опять же достигается инкапсуляцией.[/QUOTE]
О! Примеры кроссплатформенности:
1) java, какие "оптимальные" программы получаются! не находишь?
2) скажем gtk+, который под *nix'ами вроде даже как ничего работает. А под вендой, говорят, тормозит так, что...
3) OpenGL, одинаково быстро везде. Но, как ни странно, OpenGL забивает на ООП. Использование глобальных переменных, никакого полиморфизма. Единственное что используется из принципов ООП -- это инкапсуляция матричных вычислений. Но, замечу, эта инкапсуляция сделана так, что её невозможно использовать не по-назначению. То есть написать, что-нибудь семантически равное выражению "A=B*C". Где A, B, C -- вектора и матрицы. И кроме _вычислений_ ничего не инкапсулируется, даже нестандартный для C/C++ формат матрицы, приходиться использовать в том виде, в котором он есть.
/* кстати, вот тебе пример, когда инкапсуляция выглядит полезной для оптимизации. То есть, например, написать класс matrix, и метод для доступа к элементу матрицы. Класс который сам будет решать когда нужна матрица, а когда транспонированная матрица. Но прежде чем инкапсулировать, надо перебрать все варианты, того что надо будет попробовать при оптимизации программы. И как этот класс уживётся с другими способами оптимизации. И в конечном итоге, всё выливается в проведённое микроисследование, которое может сказать, что инкапсуляция не поможет отложить решение о формате матрицы на более поздние этапы разработки -- надо решать сразу. И в данном случае, это вполне законное решение. */
Кроссплатформенность, должна обеспечиваться на уровне приложения. В команде должны присутствовать программеры, которые имеют опыт программирования на всех target платформах. Всё остальное -- это полумеры.
[QUOTE=Green]Вариант третий, незнакомая платформа или незнакомые механизмы. Опять же, я абстрагируюсь от незнакомых мне вещей, от вещей, где моя компетенция не столь велика, как у разработчика библиотеки.[/QUOTE]
а нафига тогда ты пишешь под эту платформу? Да здравствуют дилетанты в программировании? Прежде чем писать, стоит поднять свою квалификацию в этих вещах так, чтобы по-крайней мере представлять себе как оно работает; возможно, почему работает (мат. обоснование); и насколько тормозно оно работает. Как правило, для такого въезжания, надо дня три чтения доков, и (очень помогает потом, при написании) возможность пообщаться со специалистом, который въезжает в тему.
[QUOTE=Green]Заметь, ты не разу не упомянул о процессе профайлинга, т.е. ты просто методом научного тыка лезешь и оптимизируешь? :)[/QUOTE]
Откуда такое обожествление профайлера? Профайлер хорош для проверки предположений, или первого "врубания в тему". А потом, проще выдирать куски кода, закидывать их в тестовые программки, и выяснять отдельно как их оптимизировать надо, и до какого уровня можно. Кроме того, программу надо долго настраивать, для получения неискажённого результата. А далеко не все программы уже настроены таким образом.
И когда, при всём при этом, при изучении программы, поиск мест для оптимизации для меня не более чем сопутствующий абстрактный интерес, то нафига я буду ипать себе моск? В тему я врублюсь разбираясь с основным интересом, а оптимизировать всё равно не буду.
Опять же замечу, ООП в реализации C++, со статической проверкой типизации, с ограничениями накладываемыми самим синтаксисом языка, меня лично устраивает в очень небольшом количестве ситуаций. Обычно, мне проще пересмотреть ООП принципы, с точки зрения соответсвия задаче, и если мне действительно не нужен полиморфизм, множественное наследование, если мне не нужны большие иерархии типов, то на хрена мне сдался C++, когда я тоже самое напишу на C?
А полезны они, согласно моему опыту, только для GUI. Ну так, отделение GUI, от, собственно, программы делает чудеса. Вплоть до того, что я напишу программу на C, а гуй на tcl/tk, python или ещё каком скрипте, которые больше подходят для этого, чем C++.
Я бы сказал, что C++ -- это отличный способ инкапсулировать кусок кода размером >20Kстрок (убогий способ оценивать размер программы, но лучше не знаю). И если этот код так инкапсулирован, то решать её _придётся_ на C++.
[QUOTE=Ireul]В принципе, любой язык будет крут при наличии знаний, опыта, и всего перечисленного у разработчика этого языка :) Язык существует в целях решения опредлённых задач. В случае С++ мы имеем все вышеперечисленные требования, а также самый широкий на сегодняшний день круг задач - создание сред(средств) решения задач. Поэтому сегодня я выбираю С++, несмотря на любые его недостатки, так как знания и опыт покроют их в любом языке. Учиться, учиться и... так далее :)[/QUOTE]
Да. Но не стоит забывать, что разные языки требуют различного опыта. На C, как показывает практика, начиная с базового понимания алгоритмики, можно научиться писать отличный код года за два-три. Для C++ этого мало. За три года можно научиться писать неплохой код, но не более этого. Можно конечно рассматривать это как преимущество. Но на мой взгляд, это проистекает от того, что (почему-то) программеры C++, как правило, чуть ли не помешаны на ООП, и считают его панацеей. Забывая что ООП -- это не более чем ограничения на оформление кода, абстракция, в рамках которой следует думать о задаче, которые используются для удобства. Они забывают при этом, что любые ограничения и абстракции, имеют свои области применимости.
ты пытаешься всегда смотреть на проблему в целом "инкапсулируясь" от деталей -- порочная практика.
[/QUOTE]
Именно так. Я охватываю проблему в целом, потом плавно вгрызаюсь по всей площади, постепенно доходя до деталей. Это нормальная рабочая практика. У меня всегда есть код, который работает и с каждой итерацией он работает все ближе к ТЗ. Это похоже на работу художника, когда сначала создаетя фон, потом наброски объектов, а потом эти объекты становятся все резче и детализированней. Ты считаешь, что сначала надо детально нарисовать на белом полотне глаз, потом другой, и т.д. все остальное?
[QUOTE=foo]
для кода на C++? Который написан так как ты описываешь? Нет, в таком случае это много только тогда, когда задача, или её критические по производительности куски _вписались_ в ограничения накладываемые на программера ООП подходом и coding-style'ом конкретного проекта. В противном случае, можно надеятся и на 50-100%.
деталей -- порочная практика.
[/QUOTE]
М-да... ну и фантазии.
[QUOTE=foo]
Живём на одном проекте. Который лет десять разрабатывался до момента когда его наконец стало возможно использовать не имея кластера на 64 проца. Наконец, PC доросли до задачи. Ещё пара проектов в процессе.
[/QUOTE]
А... ну тогда понятно...
Старый неповоротливый монстр.
[QUOTE=foo]
Любая инкапсуляция обоснована, но она должна соответствовать сложности кода под нею прячущемуся. Если неинкасулированная матричная арифметика сбивает с толку программера, то пускай такой программер идёт работать дворником.
[/QUOTE]
А если проект разноплановый?
Вот у нас есть звук, видео, графика, физика, AI, скриптовая система, HUD, сетевая поддержка. И все это ещё на пяти-шести платформах. Как думаешь, есть модули, которые один программист использует не разбираясь досконально, что там внутри?
[QUOTE=foo]
О! Примеры кроссплатформенности:
[/QUOTE]
Я сказал мультиплатформенность.
[QUOTE=foo]
Кроссплатформенность, должна обеспечиваться на уровне приложения. В команде должны присутствовать программеры, которые имеют опыт программирования на всех target платформах. Всё остальное -- это полумеры.
[/QUOTE]
ВСЕ программеры должны иметь опыт программирования на ВСЕХ платформах?
Зачем? Не вижу смысла и возможности.
[QUOTE=foo]
а нафига тогда ты пишешь под эту платформу? Да здравствуют дилетанты в программировании? Прежде чем писать, стоит поднять свою квалификацию в этих вещах так, чтобы по-крайней мере представлять себе как оно работает; возможно, почему работает (мат. обоснование); и насколько тормозно оно работает. Как правило, для такого въезжания, надо дня три чтения доков, и (очень помогает потом, при написании) возможность пообщаться со специалистом, который въезжает в тему.
[/QUOTE]
Да за тем, что всегда должен быть кто-то первый.
При чем тут дилетанты в программировании?
Пока одни программисты осваивают новую платформу и прилаживают к ней наш движок, другие уже пишут рабочий код на известной платформе, используя единый API движка.
Для того, что бы разобраться в новой платформе ни хватит не трех дней, ни трех недель.
Конкретный пример? Ты слышал о Sony PS3 ? А видел?
[QUOTE=foo]
Откуда такое обожествление профайлера?
[/QUOTE]
Да потому, что это единственный инструмент оптимизации.
Откуда такое обожествление градусника при измерении температуры? Можно ведь мерить и рукой: горячо-холодно-теплее.
[QUOTE=foo]
Профайлер хорош для проверки предположений, или первого "врубания в тему".
[/QUOTE]
Видимо у тебя нет серьезного опыта профайлинга.
[QUOTE=foo]
Кроме того, программу надо долго настраивать, для получения неискажённого результата. А далеко не все программы уже настроены таким образом.
[/QUOTE]
Ты работал с профайлерами?
[QUOTE=foo]
И когда, при всём при этом, при изучении программы, поиск мест для оптимизации для меня не более чем сопутствующий абстрактный интерес, то нафига я буду ипать себе моск? В тему я врублюсь разбираясь с основным интересом, а оптимизировать всё равно не буду.
[/QUOTE]
Не понял. Ты не оптимизируешь вообще? Или используешь какие-то заклинания и пр. шаманство?
И на С переучиваться невозможно - если знаешь С, то ты частично знаешь С++, просто нужно расширить свои знания объекно-ориентированной технологией, начать ее использовать, ну осознать незначительные отличия в реализации.
Это когда уже и не С, но ещё и не С++.
Меня такой код порой бесит. :)
Старье
Objective-C, often referred to as ObjC or more seldom as Objective C or Obj-C, is a reflective, object oriented programming language which adds Smalltalk-style messaging to C.
Today it is used primarily on Mac OS X and GNUstep, <skip>
...большинство гуру как от программирования, так и от менеджмента говорят обратное (и я с ними солидарен): проектирование и разработка - процессы итерационные, и не следует засиживаться за проектированием, а тем более полгода, все равно всех нюансов до реализации не отыскать...[/QUOTE]
Согласен, нет четкой границы между проектированием и реализацией, но проектированию-таки НУЖНО уделить должное время. Всех нюансов не отыскать, но НЕОБХОДИМО избежать как минимум таких ситуаций, что в момент реализации проекта придется вдруг отказаться от всего, что накодили, от изначального проекта, и переходить на принципиально новую концепцию, перепроектировав все заново.
...10% это достаточно много... для кода на C++? Который написан так как ты описываешь? Нет, в таком случае это много только тогда, когда задача, или её критические по производительности куски _вписались_ в ограничения накладываемые на программера ООП подходом и coding-style'ом конкретного проекта.
[/QUOTE]
Уж извини, не обижайся, но бОльшей чуши я не слышал...
Видимо, это стереотип, предрассудочное (и неправильное) понимание ООП. Его придумали не для того, чтобы ограничить программиста, или чтобы сделать код просто красивее и удобнее.
С твоим подходом к ООП, видимо, с тобой спорить уже не имеет смысла. Уж тем более, если:
[QUOTE=foo]...и если мне действительно не нужен полиморфизм, множественное наследование, если мне не нужны большие иерархии типов, то на хрена мне сдался C++...
[/QUOTE]
...
А надеяться на повышение производительности на 50-100% можно в том случае, когда проект изначально был реализован очень хреново. Ну, тут уж, извините, вопрос нужно ставить о соответствии програмеров и проектировщиков занимаемой должности. Это как в магазинах, устанавливают высокие цены, а потом кричат о 50% скидках.
...
Насчет профайлера.
[QUOTE=foo]Откуда такое обожествление профайлера? Профайлер хорош для проверки предположений, или первого "врубания в тему". А потом, проще выдирать куски кода, закидывать их в тестовые программки, и выяснять отдельно как их оптимизировать надо, и до какого уровня можно[/QUOTE]
Хм... Включаешь профайлер, выполняешь программу, и НЕПОСРЕДСТВЕННО видишь, какая функция (в твоем случае скорее функция, чем метод) выполняется дольше, на что тратится 90% времени, а на что 10%. Тебе нужно что-то другое, чтобы выяснить, что требует оптимизации?
Затем, переписываешь куски кода, которые, оказываются, выполняются дольше всего, снова профайлишь и видишь, стало ли быстрее. Что нужно еще?
Хотя у меня нет опыта профайлинга на С++ (к величайшему сожалению), даже я согласен с Green. Пару раз я пробовал профайлить на 1С и мне понравилось :)
...
О кросс-(или мульти-) платформенности.
[QUOTE=foo]
О! Примеры кроссплатформенности:
1) java, какие "оптимальные" программы получаются! не находишь?
[/QUOTE]
Остается лишь цитировать
[QUOTE=Ireul]Язык существует в целях решения опредлённых задач[/QUOTE]
Действительно, область применения Java и С/С++ разные.
На Java пишутся программки, не слишком критичные к быстродействию, а критичные скорее к скорости написания. Там можно быстро накидать нужную программулину. Пользователю нужно обработать массив данных из 1000 сотрудников. Пользователю нужно иметь программку завтра, а то, что она будет на десяток процентов медленнее соответствующего проекта С/С++, это уже не так важно, тем более, что этот проект ты будешь реализовывать пару недель, когда юзер, не дождавшись, решит задачу ручками.
Так что я считаю, что Java не такой уж неудачный инструмент в СВОЕЙ области.
Такая маленькая разница в производительности между С++ и Java может быть только в одном случае - когда оба юзают движок базы данных, написанный на С++ :)
Кстати ещё быстрее в таком случае можно вообще на делфе напрогЛамировать :)
Также от себя добавлю что вопрос сроков разработки - это вопрос прямоты рук, по крайней мере в данном примере.
Правда опять же это просто неудачный пример. Не хочу сегодня противоречить себе - и у Java есть своя область, наверняка.
Может я и ошибаюсь, но... (Поправьте, если не прав).
До диез большого смысла без .NET не имеет (я имею в виду управляемый код), поэтому выходит, что сам язык в общем сильно привязан к платформе .NET.
Короче, все задумывалось как платформенно-независимая система, но получается все наоборот - пишешь на C# и эта прога будет работать ТОЛЬКО под виндами и ТОЛЬКО если есть .NET framework.
И еще, хотя микрософт и кричит, что мол программы под управлением фреймворка будут работать не медленнее, а порой возможно и быстрее, я что-то не очень в это верю... Сам фреймворк место в памяти жрет, процессорное время жрет, подгрузка сборок тоже требует ресурсов, компиляция из байткода в машинный тоже... Откуда ускорение? Не очень я отношусь к этому фреймворку... (Повторюсь, я может и не прав, тогда поправьте меня)
я тут мучаюсь перехожу с Delphi на C++
На Java пишутся программки, не слишком критичные к быстродействию, а критичные скорее к скорости написания....
...Так что я считаю, что Java не такой уж неудачный инструмент в СВОЕЙ области.
Советую прочитать вот это. Я вижу, что сейчас дискуссия приобретает околорелигиозный характер. ИМХО, следует знать то, что востребовано, или, в крайнем случае, то, что интересно. Конечный результат - по большому счёту единственное, что интересует пользователя. Да, существует много критичных по времени выполнения задач, но есть многие некритиные. Кстати, где-то слышал, что движок Ил-2 писали на Java. Если я не вру, то вот вам яркий пример языка и задачи, с его помощью решаемой.
По поводу движка на Java - фантастический п&$#ёж. Иначе никак не сказать.
А твоему "вот это" лет почти как моей крестнице, почитаешь - ужас, каким извратом местами люди занимались. Не говоря уже о том что ИМХО VC6 для подобных тестов никак не подходит, ибо именно тогда у мелкомягких были особенные нелады с оптимизацией. В VC.NET появилист новые опции компилятора, ответственные за оптимизацию, в частности Full Program Optinisation. Найди плз что-нибудь поновее, мне и самому интересно, например, почему бы не сравнить со всем этим ещё и GCC? Тест-то практически абстрактный.
По поводу интересов пользователя - его интересует чтобы наиболее используемые им части продукта реагировали мгновенно, и неважно как при этом будут реагировать все остальные. Сто раз видел юзеров которые предпочитали быстродействие нужной части удобству использования. По сей день у многих моих знакомых стоит ACDSee6 - для сканирования и печати изображений, но для просмотра ставится IrfanView - ибо грузит быстро. Просто_конечный_результат пользователя интересует лишь тогда, когда у него нет выбора.