Уважаемый All! У нас возникла следующая проблема: в нашем проекте мы изпользуем для работы с файлами, данными в памяти стандартные потоки STL. С некоторых пор нас перестал удовлетворять механизм буферизации и мы реализовали собственную надстройку над filebuf'ом. Но после этого возникло мнение, что следует отказаться от стандартных потоков по причине их избыточной функциональности и сделать свою реализацию, не поддерживающую интерфейс iostream после чего переписать все места, где мы используем потоки. Может, кто-нибудь приведет аргументы в поддержку(или в опровержение) данной идеи? Заранее спасибо.
Здравствуйте Митрошин Александр, Вы писали:
МА>Уважаемый All! У нас возникла следующая проблема: в нашем проекте мы изпользуем для работы с файлами, данными в памяти стандартные потоки STL. С некоторых пор нас перестал удовлетворять механизм буферизации и мы реализовали собственную надстройку над filebuf'ом. Но после этого возникло мнение, что следует отказаться от стандартных потоков по причине их избыточной функциональности и сделать свою реализацию, не поддерживающую интерфейс iostream после чего переписать все места, где мы используем потоки. Может, кто-нибудь приведет аргументы в поддержку(или в опровержение) данной идеи? Заранее спасибо.
Вопрос времени и качества. Так ли требуется разработка новой библиотеки?
Набор только необходимых функций — неправильная мотивация. Посылка (избыточная функциональность) тоже звучит странно.
Здравствуйте Митрошин Александр, Вы писали:
МА>Уважаемый All! У нас возникла следующая проблема: в нашем проекте мы изпользуем для работы с файлами, данными в памяти стандартные потоки STL. С некоторых пор нас перестал удовлетворять механизм буферизации и мы реализовали собственную надстройку над filebuf'ом. Но после этого возникло мнение, что следует отказаться от стандартных потоков по причине их избыточной функциональности и сделать свою реализацию, не поддерживающую интерфейс iostream после чего переписать все места, где мы используем потоки. Может, кто-нибудь приведет аргументы в поддержку(или в опровержение) данной идеи? Заранее спасибо.
Предисловие (анекдот):
Весь запаренный программер работает ночью. К нему подходит сынок.
— Папа, папа! Правда что солнце всходит на востоке, а заходит на западе?
— Точно?
— Точно!
— Проверял?
— Проверял!
— Каждый день?
— Каждый день!
— Сынок, ТОЛЬКО НИЧЕГО НЕ МЕНЯЙ!
Мораль — по принципу в каждой шутке есть доля шутки — если все работает, то см. выше.
Математик должен быть ленивым. (c) мой бывший преподаватеть математики.
LCh>Вопрос времени и качества. Так ли требуется разработка новой библиотеки? LCh>Набор только необходимых функций — неправильная мотивация. Посылка (избыточная функциональность) тоже звучит странно.
В качестве посылки, я так понимаю не только и не столько избыточная функциональность. Поясню: если "тащить" дальше весь iostream, то с увеличением количества кода и разработчиков, использующих его, будет также увеличиваться количество ошибок: структурных, функциональных и пр., вследствии недостаточного понимания принципиального отличия(а оно есть и большое) нового iostream, также периодическое забывание того, что у нового не поддерживается более половины функциональности старого. Тоже будет наблюдаться и в процессе поддержки нового iostream. Плюс присутствуют некоторые накладные расходы (1-3 процента, но все же). Так что всплывает и мотивация — снятие излишней нагрузки (в дальнейшем) с разработчиков за счет определенного количества первоначальных затрат.
Здравствуйте viellsky, Вы писали:
V>В качестве посылки, я так понимаю не только и не столько избыточная функциональность. Поясню: если "тащить" дальше весь iostream, то с увеличением количества кода и разработчиков, использующих его, будет также увеличиваться количество ошибок: структурных, функциональных и пр., вследствии недостаточного понимания принципиального отличия(а оно есть и большое) нового iostream, также периодическое забывание того, что у нового не поддерживается более половины функциональности старого. Тоже будет наблюдаться и в процессе поддержки нового iostream. Плюс присутствуют некоторые накладные расходы (1-3 процента, но все же). Так что всплывает и мотивация — снятие излишней нагрузки (в дальнейшем) с разработчиков за счет определенного количества первоначальных затрат.
В моем понимании никакого принципиального отличия нет — мы используем тот же поток, но с усовершенствованны буфером. Почему отличий нет? Поясню, мы работаем с файлами, выполняем операции чтения/записи, с новым буфером мы будет выполнять те же операции, потому парадигма потока будет применима и здесь. Прежде чем предлагать отказ от старой, неплохо бы озвучить идею нового метода работы с файлами. Тем более у нового буфера будет поддерживаться вся функциональность filebuf за счет наследования от него и перегрузки только нужных методов.
Здравствуйте uuid, Вы писали:
U>Предисловие (анекдот): U>Весь запаренный программер работает ночью. К нему подходит сынок. U>- Папа, папа! Правда что солнце всходит на востоке, а заходит на западе? U>- Точно? U>- Точно! U>- Проверял? U>- Проверял! U>- Каждый день? U>- Каждый день! U>- Сынок, ТОЛЬКО НИЧЕГО НЕ МЕНЯЙ!
U>Мораль — по принципу в каждой шутке есть доля шутки — если все работает, то см. выше.
U>
Если есть время, и если можно поправить откровенно кривой код и избавить себя в будущем от кучи проблем, то почему бы этого не сделать? Главное, понять, что править и нужно ли это делать
МА>В моем понимании никакого принципиального отличия нет — мы используем тот же поток, но с усовершенствованны буфером. Почему отличий нет? Поясню, мы работаем с файлами, выполняем операции чтения/записи, с новым буфером мы будет выполнять те же операции, потому парадигма потока будет применима и здесь. Прежде чем предлагать отказ от старой, неплохо бы озвучить идею нового метода работы с файлами. Тем более у нового буфера будет поддерживаться вся функциональность filebuf за счет наследования от него и перегрузки только нужных методов.
1.НАСЧЕТ ФУНКЦИОНАЛЬНОСТИ А вот и не вся: половина функций будет старой, а половина новой. При этом использование "старых" функций вносит только путаницу, поскольку они воздействуют только на старый "отмерший" буфер, а на состояния нового никакого влияния не окажут. Точно также и с новыми (перегруженными). Вот вам ситуация: разработчик, не имеющий никакого понятия о том, что скрывается под красивой оболочкой родного iostream, выполняет определенный набор действий, причем в этом наборе действий используются в неопределенной последовательности как "старые", так и "новые" функции. Вопрос: что в конечном итоге получиться? Ответ, я думаю, не знает даже разработчик этого "нового" iostream. Стремный получается этот стрим.
2. НАСЧЕТ ПАРАДИГМЫ. Ж. В том-то вся и фигня, что выполняется по сути ограниченный набор функций, для которых(и только для них) создавался новый iostream. Поэтому, если разработчику надо будет что-то еще, то он с легкостью будет использовать стандартный iostream, и не будет пытаться сделать это как см. пункт1. Так-что для исключения пункта 1 и поддержания в нормальном виде пункта 2. необходимо оставить iostream As it is, а там где нужно, пользовать отдельный класс, поддерживающий необходимый набор функций. Так сказать агрегат, дружественный юзеру: пара кнопок и он все за вас сделает. В противоположность монстру, у которого торчит куча отсохших конечностей, и который при этом ведет себя совершенно непредсказуемо.
U>Предисловие (анекдот): U>Весь запаренный программер работает ночью. К нему подходит сынок. U>- Папа, папа! Правда что солнце всходит на востоке, а заходит на западе? U>- Точно? U>- Точно! U>- Проверял? U>- Проверял! U>- Каждый день? U>- Каждый день! U>- Сынок, ТОЛЬКО НИЧЕГО НЕ МЕНЯЙ!
U>Мораль — по принципу в каждой шутке есть доля шутки — если все работает, то см. выше.
А если сына решит сделать еще пару солнц, которые будут летать по замысловатой траектории?
Здравствуйте Митрошин Александр, Вы писали:
МА>Уважаемый All! У нас возникла следующая проблема: в нашем проекте мы изпользуем для работы с файлами, данными в памяти стандартные потоки STL. С некоторых пор нас перестал удовлетворять механизм буферизации и мы реализовали собственную надстройку над filebuf'ом. Но после этого возникло мнение, что следует отказаться от стандартных потоков по причине их избыточной функциональности и сделать свою реализацию, не поддерживающую интерфейс iostream после чего переписать все места, где мы используем потоки. Может, кто-нибудь приведет аргументы в поддержку(или в опровержение) данной идеи? Заранее спасибо.
Идея плохая, IMHO.
Избыточную функциональность в данном случае бесплатна:
она уже реализована, причем реализована правильно и не в вашем коде, а в библиотеке — ее поддержка почти ничего не стоит.
если она не нужна, ее можно не использовать — соответственно, она не только не тормозит, но даже не порождает дополнительного кода, поскольку реализована как шаблон (если только производитель библиотеки не скомпилировал ее заранее, как в случае стримов из MSVC).
Переписывание стримов на свои стоит денег. Поддержка — тоже. Если когда-либо приложение придется портировать, эти деньги придется потратить снова
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте Митрошин Александр, Вы писали:
МА><...>возникло мнение, что следует отказаться от стандартных потоков по причине их избыточной функциональности и сделать свою реализацию, не поддерживающую интерфейс iostream после чего переписать все места, где мы используем потоки.
Некоторые соображения на эту тему:
1. В своё время мы так и сделали. Только нам не пришлось ничего переписывать, мы заранее были к этому готовы. И не только по потокам, а и по некоторым другим сущностям тоже. По крайней мере фраза "Одни STL-ем не пользуются, а другие с ним воюют" к нашей библиотеке не подходит
2. По интерфейсу:
а) операции, выполняющиеся точно одинаково с STL должны иметь точно такой же интерфейс (во избежание путаницы)
б) операции, отличающиеся в ключевых местах (даже не значительно) должны иметь "достаточно другой" интерфейс
в) инварианты, пре/пост-условия, принципы, основные отличия и т.п. должны быть тщательно документированы и доведены до разработчиков
3. По решению (менять/не менять):
а) какие конкретные преимущества даёт переход (скорость, память, простота кода, стоимость сопровождения, время разработки, етк)
б) какие проблемы решает переход, какие не решает
в) какие альтернативные методы существуют (класс-оболочка, макросы, етк)
г) сколько стоит переход (объем кода, подлежащего изменению + переподготовка разработчиков и время на адаптацию)
д) оценить риски, связанные с переходом (надёжность кода {тестирование, отладка}, расширяемость, стыкуемость с другими решениями/модулями/кодом, етк)
Также очень интересно, что именно не понравилось в std::iostream и какие упрощения/изменения/расширения планируется сделать?
S>Идея плохая, IMHO. S>Избыточную функциональность в данном случае бесплатна: S>она уже реализована, причем реализована правильно и не в вашем коде, а в библиотеке — ее поддержка почти ничего не стоит. S>если она не нужна, ее можно не использовать — соответственно, она не только не тормозит, но даже не порождает дополнительного кода, поскольку реализована как шаблон (если только производитель библиотеки не скомпилировал ее заранее, как в случае стримов из MSVC). S>Переписывание стримов на свои стоит денег. Поддержка — тоже. Если когда-либо приложение придется портировать, эти деньги придется потратить снова
O>Также очень интересно, что именно не понравилось в std::iostream и какие упрощения/изменения/расширения планируется сделать?
Все оч. просто — осуществляется запись и чтение из файла участков, каждый из которых не выходит за пределы какой-то одной секции. Причем весь файл состоит из этих секций фиксированного размера. Плюс этих файлов несколько — у каждого свой размер секции. Таким образом весь процесс можно очень легко прокэшировать — было выявлено реальное увеличение скорости работы в 4 — 10 раз по сравнению со стандартным fstream. Таким образом был выявлен "набор" функций:
запись(что, куда, сколько)
чтение(во что, откуда, сколько)
Поскольку уже было написан опр. кол-во кода, использующего fstream, было предложено два пути:
1. создать класс, поддерживающий эти 2 функции и переписать созданный код.
2. перегрузить filebuf, который пользует fstream — и тогда кода переписывать практически не надо. Практически — это надо проследить, чтобы в коде вызывались только нужные функции и в нужном порядке.
Вот вам вопрос — какой путь избрать? Я выбрал 1-й., что и пояснял в предыдущих ответах.
Здравствуйте viellsky, Вы писали:
S>>Идея плохая, IMHO. S>>Избыточную функциональность в данном случае бесплатна: S>>она уже реализована, причем реализована правильно и не в вашем коде, а в библиотеке — ее поддержка почти ничего не стоит. S>>если она не нужна, ее можно не использовать — соответственно, она не только не тормозит, но даже не порождает дополнительного кода, поскольку реализована как шаблон (если только производитель библиотеки не скомпилировал ее заранее, как в случае стримов из MSVC). S>>Переписывание стримов на свои стоит денег. Поддержка — тоже. Если когда-либо приложение придется портировать, эти деньги придется потратить снова
V>Прочти пож.здесь
Как несложно заметить, я отвечал на вопрос Александра Митрошина, где ни слова не было сказано о том, что свой filebuf был написан с ошибками. Что же касательно здесь
, то отвечу по пунктам:
V>1.НАСЧЕТ ФУНКЦИОНАЛЬНОСТИ А вот и не вся: половина функций будет старой, а половина новой.
Это возможно только в случае, если "свой" filebuf реализован неправильно. При этом работать правильно не будет, AFAIR, ничего
V>При этом использование "старых" функций вносит только путаницу, поскольку они воздействуют только на старый "отмерший" буфер, а на состояния нового никакого влияния не окажут.
Никакого "старого отмершего буфера" быть не должно. Должен быть только новый буфер — наследник старого.
V>Точно также и с новыми (перегруженными).
Перегрузка функций std::basic_ostream, работающих с буфером, в наследнике — достаточно странная идея сама по себе.
V>Вот вам ситуация: разработчик, не имеющий никакого понятия о том, что скрывается под красивой оболочкой родного iostream, выполняет определенный набор действий, причем в этом наборе действий используются в неопределенной последовательности как "старые", так и "новые" функции. Вопрос: что в конечном итоге получиться? Ответ, я думаю, не знает даже разработчик этого "нового" iostream. Стремный получается этот стрим.
Разработчик "нового" стрима, совместимого со стандартным, разрабытавает его следующим образом:
1) Пишет своего наследника std::basic_streambuf, реализующего необходимые примитивные операции. Для определенности назовем его my_super_duper_filebuf. Самая сложная часть работы.
2) Пишет "свои" my_super_duper_istream/my_super_duper_ostream и т.д:
заводит переменную-член класса типа my_super_duper_filebuf.
пишет конструкторы, инициализирующие (или нет — но это чуть-чуть сложнее ) my_super_duper_filebuf и вызывающие конструкторы предка и передающих ему ссылку на my_super_duper_filebuf
при необходимости, дописывает пару-тройку функций, специфичных для данного класса — например, is_open/close/open для файловых стримов и т.д.
Собственно, функциональность стрима почти автоматически получается совпадающей или превосходящей функциональность стандартных стримов.
V>2. НАСЧЕТ ПАРАДИГМЫ. Ж. В том-то вся и фигня, что выполняется по сути ограниченный набор функций, для которых(и только для них) создавался новый iostream.
Это меняет суть дела. Если в новом классе не нужны ни функции read/write, ни операторы ">>" или "<<", ни функции позиционирования внутри стрима, не называйте его стримом и не путайте себя и других.
V>Поэтому, если разработчику надо будет что-то еще, то он с легкостью будет использовать стандартный iostream, и не будет пытаться сделать это как см. пункт1. Так-что для исключения пункта 1 и поддержания в нормальном виде пункта 2. необходимо оставить iostream As it is, а там где нужно, пользовать отдельный класс, поддерживающий необходимый набор функций. Так сказать агрегат, дружественный юзеру: пара кнопок и он все за вас сделает. В противоположность монстру, у которого торчит куча отсохших конечностей, и который при этом ведет себя совершенно непредсказуемо.
Никаких "отсохших конечностей" быть не может в принципе, если только разработчику не хватило дури сделать два буфера там, где нужен один — наследник std::basic_streambuf.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте Sergey, Вы писали:
S>Здравствуйте viellsky, Вы писали:
S>>>Идея плохая, IMHO. S>>>Избыточную функциональность в данном случае бесплатна: S>>>она уже реализована, причем реализована правильно и не в вашем коде, а в библиотеке — ее поддержка почти ничего не стоит. S>>>если она не нужна, ее можно не использовать — соответственно, она не только не тормозит, но даже не порождает дополнительного кода, поскольку реализована как шаблон (если только производитель библиотеки не скомпилировал ее заранее, как в случае стримов из MSVC). S>>>Переписывание стримов на свои стоит денег. Поддержка — тоже. Если когда-либо приложение придется портировать, эти деньги придется потратить снова
V>>Прочти пож.здесь
V>>Там все было написано...
S>Как несложно заметить, я отвечал на вопрос Александра Митрошина, где ни слова не было сказано о том, что свой filebuf был написан с ошибками. Что же касательно здесь
, то отвечу по пунктам:
V>>1.НАСЧЕТ ФУНКЦИОНАЛЬНОСТИ А вот и не вся: половина функций будет старой, а половина новой.
S>Это возможно только в случае, если "свой" filebuf реализован неправильно. При этом работать правильно не будет, AFAIR, ничего
V>>При этом использование "старых" функций вносит только путаницу, поскольку они воздействуют только на старый "отмерший" буфер, а на состояния нового никакого влияния не окажут.
S>Никакого "старого отмершего буфера" быть не должно. Должен быть только новый буфер — наследник старого.
V>>Точно также и с новыми (перегруженными).
S>Перегрузка функций std::basic_ostream, работающих с буфером, в наследнике — достаточно странная идея сама по себе.
V>>Вот вам ситуация: разработчик, не имеющий никакого понятия о том, что скрывается под красивой оболочкой родного iostream, выполняет определенный набор действий, причем в этом наборе действий используются в неопределенной последовательности как "старые", так и "новые" функции. Вопрос: что в конечном итоге получиться? Ответ, я думаю, не знает даже разработчик этого "нового" iostream. Стремный получается этот стрим.
S>Разработчик "нового" стрима, совместимого со стандартным, разрабытавает его следующим образом:
S>1) Пишет своего наследника std::basic_streambuf, реализующего необходимые примитивные операции. Для определенности назовем его my_super_duper_filebuf. Самая сложная часть работы.
S>2) Пишет "свои" my_super_duper_istream/my_super_duper_ostream и т.д: S> заводит переменную-член класса типа my_super_duper_filebuf. S> пишет конструкторы, инициализирующие (или нет — но это чуть-чуть сложнее ) my_super_duper_filebuf и вызывающие конструкторы предка и передающих ему ссылку на my_super_duper_filebuf S> при необходимости, дописывает пару-тройку функций, специфичных для данного класса — например, is_open/close/open для файловых стримов и т.д.
S>Собственно, функциональность стрима почти автоматически получается совпадающей или превосходящей функциональность стандартных стримов.
V>>2. НАСЧЕТ ПАРАДИГМЫ. Ж. В том-то вся и фигня, что выполняется по сути ограниченный набор функций, для которых(и только для них) создавался новый iostream.
S>Это меняет суть дела. Если в новом классе не нужны ни функции read/write, ни операторы ">>" или "<<", ни функции позиционирования внутри стрима, не называйте его стримом и не путайте себя и других.
V>>Поэтому, если разработчику надо будет что-то еще, то он с легкостью будет использовать стандартный iostream, и не будет пытаться сделать это как см. пункт1. Так-что для исключения пункта 1 и поддержания в нормальном виде пункта 2. необходимо оставить iostream As it is, а там где нужно, пользовать отдельный класс, поддерживающий необходимый набор функций. Так сказать агрегат, дружественный юзеру: пара кнопок и он все за вас сделает. В противоположность монстру, у которого торчит куча отсохших конечностей, и который при этом ведет себя совершенно непредсказуемо.
S>Никаких "отсохших конечностей" быть не может в принципе, если только разработчику не хватило дури сделать два буфера там, где нужен один — наследник std::basic_streambuf.
Скажу кратко: в том то и дело, что создаваемая фигня стримом-то и не является. А стримом она была сделана для того, чтобы не переписывать код, где используется стрим. Поэтому я лично ратую за то, чтобы создать отдельный класс. Поэтому и шла речь об отмерших конечностях и пр. Так что все вышеназванные нападки по-сути верны лишь в случае, если-бы в самом начале новый стрим позиционировался как стрим, а не заплатка.
V>Скажу кратко: в том то и дело, что создаваемая фигня стримом-то и не является. А стримом она была сделана для того, чтобы не переписывать код, где используется стрим. Поэтому я лично ратую за то, чтобы создать отдельный класс.
Не верю. Раз был какой-то код, который с этой сущностью работал как со стримом, то эта сущность является, помимо всего прочего, еще и стримом.
V>Поэтому и шла речь об отмерших конечностях и пр. Так что все вышеназванные нападки по-сути верны лишь в случае, если-бы в самом начале новый стрим позиционировался как стрим, а не заплатка.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте orangy, Вы писали:
O>Здравствуйте viellsky, Вы писали:
V>>Скажу кратко: <...> O>Хочешь быть краток — будь им. Пожалуйста, укротите свою оверквотилку...
Здравствуйте viellsky, Вы писали:
V>>>Скажу кратко: <...> O>>Хочешь быть краток — будь им. Пожалуйста, укротите свою оверквотилку... V>Не в тему...
Уважаемый, из ~4522 байт сообщения, ~4103 являются копией предыдущего сообщения, которое отнимает время (на просмотр, не выделено ли чего болдом, не вставлено ли где комментария), траффик и т.п. Я не вижу в этой цитате ничего настолько важного, чтобы приводить её целиком. Будьте добры, уважайте время других участников форумов. Спасибо заранее.
Запрещается излишнее цитирование (overquoting). Если вы отвечаете на письмо, цитируйте из него только те отрывки, которые действительно необходимы для понимания, о чём идёт речь.
Здравствуйте viellsky, Вы писали:
S>>Не верю. Раз был какой-то код, который с этой сущностью работал как со стримом, то эта сущность является, помимо всего прочего, еще и стримом.
V>Хех, ну так да типа. Но по сути в ней используются две+две функции:
V>открыть_файл V>писАть(что, куда, сколько) V>читать(во что, откуда, сколько) V>закрыть_файл
У стандартных стримов нет функций "писАть(что, куда, сколько)", но есть функции "установить позицию записи" и писать(что, чколько). Если имелись в виду именно они, то да, это стрим. Если удалось сделать работоспособную реализацию этих двух функций и flush, переопределив буфер, то остальная функциональность стандартного ostream (операторы форматного вывода) будет реализована автоматически. Примерно то же самое относится и к istream.
V>Ну, если это типичный стрим, то человек блин типичный самолет(по земле могет, а летать не надо)
Ладно, а что в твоем понимании "типичный стрим"?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.