Re[17]: # еще раз: сколько стоит одна строка кода на си?
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 18.12.09 17:45
Оценка:
Здравствуйте, WolfHound, Вы писали:

E>>Не все так просто.Вот ссылка из документа об использовании исключений в Windows kernel

WH>То что исключения в MSVC реализованы плохо ИМХО знают все.
WH>Вот только что их мешает реализовать хорошо?

Глядя на простыни мануалов на тему "как использовать исключения в с++" слабо верится что проблема именно у msvc.
Re[14]: # еще раз: сколько стоит одна строка кода на си?
От: gear nuke  
Дата: 18.12.09 17:45
Оценка: +1
Здравствуйте, мыщъх, Вы писали:

М>имхо начинать с асма в нашу эпоху будет тяжело. уж лучше сначала си


Си это ассемблер PDP-11. ПРичем сделан так, что позволяет понять его сходу... и неправильно. А переучиваться всегда дороже.

М>и что самое смешное, люди которые готовы убить за goto, пропагандируют исключения, которые еще хуже, чем goto, поскольку goto err это не лапша и сразу понятно кто у нас обрабатывает ошибку (ну или long jump)

М>, а вот исключения вообще непонятно кто и как обрабатывает.

Самое смешное — диспетчер исключений обрабатывает и longjmp Теперь понятно?

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


Ты не знаешь С++, поэтому твоя точка зрения суть догадки. Если он действительно понимает плюсы, то конечно сделает на С (в смысле — сможет), но вряд ли будет тратить своё время так неэффективно.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[12]: # еще раз: сколько стоит одна строка кода на си?
От: gear nuke  
Дата: 18.12.09 18:01
Оценка:
Здравствуйте, мыщъх, Вы писали:

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


Почему статический массив будет на 2 порядка быстрее автоматического, который по факту всегда в кеше?
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[3]: # еще раз: сколько стоит одна строка кода на си?
От: lyk  
Дата: 18.12.09 18:03
Оценка:
Здравствуйте, мыщъх, Вы писали:

М> программа ищет определенную последновательность кода с учетом возможных вариаций. вообще-то по уму тут нужно юзать либу регулярных выражений. если бы знал — заюзал.


Зачем регулярные — строится автомат с состояниями, условиями переходов. Причем — если на asm — все будет на регистрах и просто летать Правда, сейчас оптимизаторы С тоже очень хитрые. С регулярными писать на порядок меньше, но как там там реализованы потроха... Ну это дело вкуса.
Re[17]: # еще раз: сколько стоит одна строка кода на си?
От: мыщъх США http://nezumi-lab.org
Дата: 18.12.09 18:34
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Здравствуйте, CreatorCray, Вы писали:


ТКС> Достаточно, конечно. Для многого вообще и ассемблера достаточно.

TKC> Но я просто пояснял, каким образом исключения могут быть быстрее кодов возврата,
стоп. исключения (программные, т.к. аппаратных у нас немного и они на каждой платформе разные и "стоят" очень дорого в смысле памяти/тактов ЦП) могут быть реализованы через посылку сообщений. если произошло нечто ужасное, то тащить ошибку через кучу уровней действительно глупо и рисковано (вдруг где-то забудем вставить проверку). а вот послать сообщение -- самое то. адресат сообщения может быть где угодно и он получит его немедленно (допустим, через таблицу вызовов), т.е. практически без накладных расходов.

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

это не значит, что нужно переизобретать плюсы но утверждение, что на плюсах можно сделать более быстрый код, чем на си по меньшей мере сомнительно и требует доказательств. или хотя бы обоснований. кстати, кто мне объяснит почему в ms vc выбор исключения реализован так, как он там реализован? это же ужос. именно потому исключения и не рекоммендуется бросать в ядре.

TKC> а не затевал спор об их избыточности/необходимости в неоговоренных заранее ситуациях

язык определяет мышление хотим мы того или нет. постоянно сталкиваюсь, что плюсовики тяготеют к решением в общем виде, в то время как сишники решают задачу в частном виде, что в разы быстрее. вон тут в одной текущей задаче, которую сначала показали плюсовику и спросили сколько займет ее решение, он сказал, тут типа нам нужно писать могучий движок и это проект на полгода. его коллега (сишник) поинтересовался: а зачем? ведь _поставленная_ задача укладывается в сотню строк кода. ответ был ошеломляющим: "ну и что мы так и будем по сотне строк кода писать для решения частных задач каждый раз как они возникают? задачи надо решать раз и навсегда!!!"

CC>>Причём выброс исключения на порядки тяжелее чем возврат кода ошибки.

ТКС>Да. Поэтому область их применения ограничивается теми областями, где ошибки возникают на порядки реже,
стоп! если ошибки все-таки возникают, то это ведет к возможности доса.

TKC> чем нормальное завершение работы. А это, как ни странно, подавляющее большинство кода

согласно парадигме ООП о частоте возникновения ощибок место их возникновения знать не может. например, ошибка выдления памяти: как часто она возникает? ответ: ну вообще-то при нормальном положении дел не возникает вообще, но если "кривыми" запросами заставить выпрыгивать ее постоянно, то... капец производительности.

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

ЗЫ. я не противник исключений. но ругая си за "...дайте детям динамит", исключения в плюсах выглядят как "...дали террористам атомную бомбу и средство ее доставки". наличие исключений (и их агрессивная пропаганда) приводят к их бездумному использованию. поэтому, если мы на 100% не уверены, что знаем как юзать исключения, их лучше не юзать.

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

ЗЫ.ЗЫ.ЗЫ. а что делать если прототип функции объявлен как void remove_comments(char *s), нам менять его нельзя, а нужно удалить из строки си и си++ комментарии? а если комментарии кривые? допустим, вложенные /* /* */ */ ? вполне реальный пример из жизни. тестовое задание от макровижн. когда они мне его прислали первый раз, я сказал, что void не катит. через год они присылают тоже самое (!) задание с тем же (!) прототимом, но с припиской на полях: s указаывает на строку с комментами _по_ _стандарту_. т.е. согласно ТЗ ошибки возникнуть не может. но а если таки выясняется, что комменты у нас не по стандарту? что делать-то? менять прототип мы не могем. я плюнул и в обработчике ошибок воткнул *s = 0. не уверен, что правильно, но...
а что было еще делать? исключение кидать? а кто его ловить будет? а не станет ли оно намного большей неожиданностью, чем непонятного почему обнулившаяся строка?
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[19]: # еще раз: сколько стоит одна строка кода на си?
От: eagersh  
Дата: 18.12.09 18:42
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, eagersh, Вы писали:


E>>Я пытаюсь сказать что

WH>Ты пытаешься прыгать с темы на тему пытаясь отстоять сказанную не подумав глупость.

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

WH>И к чему тут эта банальность?

А в чем глупость? В том что С почти не используется в системном програмировании это правда.А если используется то с большимы ограничениями.Почему? Потому что есть причины которые я тебе часть показал.Я уже приводил этот документ выше, но для тебя приведу еще раз.
http://www.microsoft.com/whdc/driver/kernel/KMcode.mspx


E>>Есть и задачи где можна использовать только ассемблер.Там даже С нельзя, несмотря на его хорошую оптимизацию по коду.

WH>И что это за задачи таки?
Ну например PXEloader с каким нибудь network stack. Так как это работает в real mode то идет борьба за каждый байт памяти.
Ну и разный start boot in embedded systems.
Re[19]: # еще раз: сколько стоит одна строка кода на си?
От: eagersh  
Дата: 18.12.09 19:01
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, eagersh, Вы писали:


E>>Что бы такие вещи говорить надо самому написать операционку.Только тогда можно правильно оценить какой язык выбрать для реализации.


GN>А в чем у *nix, кстати, проблема? Они использовали ключевый слова С++ в своих гнусных целях? Re: Попинайте C++ framework для DDK
Автор: MShura
Дата: 26.05.08

Просто все изначально было написанно на С для Linux в начале 90-х. На С++ не имело смысла переписовать. Переписать конечно можно было, но преимуществ не получили бы.
Но С++ не все так плохо в системном програмировании.Можно програмировать на нем тоже, но правда с ограничениями.Надо хорошо понимать эти ограничения, и как их обходить. Microsoft например сейчас широко использует кернел API — WDF которая написанна на С++.Но правда Microsoft все еще не рекомендует использовать С++ для написания драйверов. Их понять можно, так как драйвера фактически часть OS со всеми вытекающими последствиями.
Re[4]: # еще раз: сколько стоит одна строка кода на си?
От: мыщъх США http://nezumi-lab.org
Дата: 18.12.09 19:42
Оценка:
Здравствуйте, lyk, Вы писали:

lyk>Здравствуйте, мыщъх, Вы писали:


М>> программа ищет определенную последновательность кода с учетом возможных вариаций. вообще-то по уму тут нужно юзать либу регулярных выражений. если бы знал — заюзал.


lyk> Зачем регулярные — строится автомат с состояниями, условиями переходов. Причем — если на asm

с удовольствием бы написал на асм. на си не хватает goto (оно там есть, но не приветствуется), поэтому замуил спагетти из кучи continue/break, уложившись в 16 строк, уместив их в одной функции.

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

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

> все будет на регистрах и просто летать

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

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

> но как там там реализованы потроха... Ну это дело вкуса.
с регулярными да, задача была бы решена быстрее. хотя не уверен. отладчика регулярных выражений еще не видел. и у всех них язык write-only.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[13]: # еще раз: сколько стоит одна строка кода на си?
От: мыщъх США http://nezumi-lab.org
Дата: 18.12.09 20:40
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, мыщъх, Вы писали:


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


GN>Почему статический массив будет на 2 порядка быстрее автоматического, который по факту всегда в кеше?fr

имеется ввиду "выделение памяти под массив". а если массив еще не дай бог и иницилизированный, то это вообще капец в случае со стеком. самый классический пример: char buf[]="hello, world!\n". менее классический, но так же встречающийся это int matrix[x][y][z] = ... ;

но даже если массив не иницилизирован. объявляя в статике int buf[xxl] мы ничего не теряем. даже память не коммитим. вот как воспользуемся буфером (если вообще воспользуемся) так ось и закоммитит. если же массив локальный ОС выделяет память при входе в функцию. и эта функция пробегается по каждой странице массива даже если память была выделена ранее (компилер же не знает была выделеена память или нет). допустим, у нас массив на 400 кб. тогда компилятор воткнет скрытый цикл на сотню итераций. если цикл функцией реально используется хотя бы на 30% — потери производительности невелики, но что делать, если массив размером с максимально допустимую длину некой структуры (строки), а в рельности функция работает намного с более короткими строками?

ЗЫ. я ж сказал "иногда" (см. выделенное). в _общем_ случае различие в производительности действительно скорее всего не будет заметно.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[18]: # еще раз: сколько стоит одна строка кода на си?
От: Тот кто сидит в пруду Россия  
Дата: 18.12.09 20:48
Оценка:
Здравствуйте, мыщъх, Вы писали:

ТКС>> Достаточно, конечно. Для многого вообще и ассемблера достаточно.

TKC>> Но я просто пояснял, каким образом исключения могут быть быстрее кодов возврата,
М>стоп. исключения (программные, т.к. аппаратных у нас немного и они на каждой платформе разные и "стоят" очень дорого в смысле памяти/тактов ЦП) могут быть реализованы через посылку сообщений. если произошло нечто ужасное, то тащить ошибку через кучу уровней действительно глупо и рисковано (вдруг где-то забудем вставить проверку). а вот послать сообщение -- самое то. адресат сообщения может быть где угодно и он получит его немедленно (допустим, через таблицу вызовов), т.е. практически без накладных расходов.

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


М>это не значит, что нужно переизобретать плюсы но утверждение, что на плюсах можно сделать более быстрый код, чем на си по меньшей мере сомнительно и требует доказательств. или хотя бы обоснований. кстати, кто мне объяснит почему в ms vc выбор исключения реализован так, как он там реализован? это же ужос. именно потому исключения и не рекоммендуется бросать в ядре.


Собственно никто и не спорит, что на C вполне можно организовать закат солнца в ручную. Но часто ли на setjmp/longjmp организуют обычную прикладную логику? Да ни в жисть. В то время как на плюсах аналогичный механизм уже есть, причем — удобный.

TKC>> а не затевал спор об их избыточности/необходимости в неоговоренных заранее ситуациях

М>язык определяет мышление хотим мы того или нет. постоянно сталкиваюсь, что плюсовики тяготеют к решением в общем виде, в то время как сишники решают задачу в частном виде, что в разы быстрее. вон тут в одной текущей задаче, которую сначала показали плюсовику и спросили сколько займет ее решение, он сказал, тут типа нам нужно писать могучий движок и это проект на полгода. его коллега (сишник) поинтересовался: а зачем? ведь _поставленная_ задача укладывается в сотню строк кода. ответ был ошеломляющим: "ну и что мы так и будем по сотне строк кода писать для решения частных задач каждый раз как они возникают? задачи надо решать раз и навсегда!!!"

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

CC>>>Причём выброс исключения на порядки тяжелее чем возврат кода ошибки.

ТКС>>Да. Поэтому область их применения ограничивается теми областями, где ошибки возникают на порядки реже,
М>стоп! если ошибки все-таки возникают, то это ведет к возможности доса.

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

TKC>> чем нормальное завершение работы. А это, как ни странно, подавляющее большинство кода

М>согласно парадигме ООП о частоте возникновения ощибок место их возникновения знать не может. например, ошибка выдления памяти: как часто она возникает? ответ: ну вообще-то при нормальном положении дел не возникает вообще, но если "кривыми" запросами заставить выпрыгивать ее постоянно, то... капец производительности.

А ей в этом случае по любому капец, что у нас new исключения кидает, что результат malloc проверяем. Только если в случае с new упадет 95% программ, в случае с malloc (или старорежимным некидающим new) эта доля превышает, по моим наблюдениям, 99%.

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


Ну так обязнность думать головой никто не отменял Мешают в каком-то коде исключения — значит надо писать без них.

М>ЗЫ. я не противник исключений. но ругая си за "...дайте детям динамит", исключения в плюсах выглядят как "...дали террористам атомную бомбу и средство ее доставки". наличие исключений (и их агрессивная пропаганда) приводят к их бездумному использованию. поэтому, если мы на 100% не уверены, что знаем как юзать исключения, их лучше не юзать.


По мне так наоборот — если мы на 100% не уверены, что справимся без исключений, лучше их использовать. Я про прикладной код естественно, без каких-то специфических ограничений. Ну а если логика позволяет и без кодов возврата, и без исключений обойтись — ну так мы в таком случае ничего не теряем, значит ни одного throw в коде и не будет.

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


Ну вот как раз если скатываться к текстовым редакторам, то исключениям альтернативы я не вижу. Пишем для самого низкого уровня библиотеку, кидающую исключения (или берем готовую), закрываем try/catch самый верхний уровень (WinMain и WndProc или что у нас там в целевой системе, а так же все вспомогательные нити) и собственно в коде редактора вообще не паримся на тему обработки ошибок. Естественно, повсеместно используем RAII — оно и без исключений полезно. Чуть какая двусмысленная ситуация — кидаем исключение, сверху поймают и мессаджбокс покажут. И юзер по крайней мере узнает, что файл заблокирован другой программой, а не пустой, как ему бы показалось без обработки ошибок.

М>ЗЫ.ЗЫ.ЗЫ. а что делать если прототип функции объявлен как void remove_comments(char *s), нам менять его нельзя, а нужно удалить из строки си и си++ комментарии? а если комментарии кривые? допустим, вложенные /* /* */ */ ? вполне реальный пример из жизни. тестовое задание от макровижн. когда они мне его прислали первый раз, я сказал, что void не катит. через год они присылают тоже самое (!) задание с тем же (!) прототимом, но с припиской на полях: s указаывает на строку с комментами _по_ _стандарту_. т.е. согласно ТЗ ошибки возникнуть не может. но а если таки выясняется, что комменты у нас не по стандарту? что делать-то? менять прототип мы не могем. я плюнул и в обработчике ошибок воткнул *s = 0. не уверен, что правильно, но...


Конкретно с комментарием лично я бы оставил как есть. Ну то есть если встретили одинарный /* — выкидываем все до конца (хотя тут по уму все равно надо бы возвращать ошибку), если */ — возвращаем все как есть, это не комментарий, пусть с этим следующий уровень трахается.

М>а что было еще делать? исключение кидать? а кто его ловить будет? а не станет ли оно намного большей неожиданностью, чем непонятного почему обнулившаяся строка?


Ну это всего лишь не полностью сформулированное ТЗ. В жизни у меня таких почти не бывает, потому что я либо начинаю пытать заказчика, пока не выложит, для чего ему это надо, либо сам додумываю — если это в моей компетенции.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[14]: # еще раз: сколько стоит одна строка кода на си?
От: legogogo  
Дата: 18.12.09 21:15
Оценка: -1
Здравствуйте, мыщъх, Вы писали:

М>имеется ввиду "выделение памяти под массив". а если массив еще не дай бог и иницилизированный, то это вообще капец в случае со стеком. самый классический пример: char buf[]="hello, world!\n". менее классический, но так же встречающийся это int matrix[x][y][z] = ... ;



откройте для себя alloca();
Компьютер — это конечный автомат. Потоковое программирование нужно тем, кто не умеет программировать конечные автоматы (c) Алан Кокс
Re[15]: # еще раз: сколько стоит одна строка кода на си?
От: Тот кто сидит в пруду Россия  
Дата: 18.12.09 21:55
Оценка: 1 (1)
Здравствуйте, legogogo, Вы писали:

М>>имеется ввиду "выделение памяти под массив". а если массив еще не дай бог и иницилизированный, то это вообще капец в случае со стеком. самый классический пример: char buf[]="hello, world!\n". менее классический, но так же встречающийся это int matrix[x][y][z] = ... ;


L>откройте для себя alloca();


Тебе не про то пишут, а про скрытую инициализацию. Запись
char buf[]="hello, world!\n"

в отличие от записи
char const *buf="hello, world!\n"

скопирует строку в локально объявленный массив. В ряде случаев эти расходы могут стать заметными. Например, я когда-то подобную фигню в xml-парсере boost::serialization обнаружил — удалось нахаляву на пару процентов скорость загрузки увеличить. При том что там медленные файловые стримы использовались и вообще много всякой работы. Поэтому про подобные вещи надлежит помнить и вовремя голову включать, константы выносить в статику. Там правда есть шанс лохануться в другую сторону и упустить из виду многопоточность, если вдруг потом вместо константы потребуется переменная
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[19]: # еще раз: сколько стоит одна строка кода на си?
От: мыщъх США http://nezumi-lab.org
Дата: 18.12.09 22:23
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Здравствуйте, мыщъх, Вы писали:


ТКС> Собственно никто и не спорит, что на C вполне можно организовать закат солнца в ручную.

ТКС> Но часто ли на setjmp/longjmp организуют обычную прикладную логику? Да ни в жисть.
ТКС> В то время как на плюсах аналогичный механизм уже есть, причем — удобный.
с тем, что механизм есть — согласен. с тем что удобный — могу поспорить, но не буду. потому как для этого же его сначала изучить надо. я же сторонник подхода: если знаю как написать что-то за разумное время, то лучше писать самому, чем использовать сторонние компоненты. причем если в библиотеки хотя бы можно заглянуть, то особенности реализации исключений на данном компиляторе под данной осью...

M> укладывается в сотню строк кода. ответ был ошеломляющим: "ну и что мы так и будем по сотне

M> строк кода писать для решения частных задач каждый раз как они возникают? задачи надо
M> решать раз и навсегда!!!"

ТКС> Встречаются иногда такие кадры, ага. Я раньше думал, что они испорченные джавой.

это, конечно, крайний случай, но и в повседневной жизни спрашивая плюсовиков: а зачем тут это? я получаю ответы: а вдруг понадобится?

ведь в решении задачи важно понять что же нам _действительно_ надо. известна же хохма: препод: дан массив из N целых чисел, от 0 до N-1, где каждое число не может встречаться больше одного раза. отсортировать. вопрос из зала: скажите: на хрена нам массив?

> Обратная крайность — когда заранее известно, что частных случаев будет не меньше 30,

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

ТКС> Когда-то ведет, когда-то не ведет. Если мы тихо мирно из файла или даже сокета читаем, и нам лень

TKC> на каждом из 10 уровней при каждом чтении проверку писать — какой тут нафиг дос?
смотря как читать и что читать. проверок все равно будет куча. допустим, мы ожидаем увидеть: XXX N M "<yyy@zzz>". какая разница с точки зрения парсера, то ли соединение порвалось, то ли кто-то скобку не закрыл.

ТКС> Ну так обязнность думать головой никто не отменял

TKC> Мешают в каком-то коде исключения — значит надо писать без них.
а если мне мешают исключения в чужом коде? причем мешают не сами исключения, и даже не код, а скорость внесения в него изменений. допустим, прошу коллегу чего-то добавить в его модуле, потому как это нужно моему (мой модуль хочет сообщить о чем-то важном пра-пра-пра материнской функции). коллега печатльно смотрит на свой код и грит, "слушай, а давай мы щас откомилирующешь свой модуль в программу, вернешь вывод в xml, а мы его запустим скриптом на руби и распарсим". вот... такие у нас исключения.

ТКС> По мне так наоборот — если мы на 100% не уверены, что справимся без исключений, лучше их использовать.

вопрос: как? рецептов много, ни одного правильного.

TKC> Я про прикладной код естественно, без каких-то специфических ограничений. Ну а если логика позволяет

TKC> и без кодов возврата, и без исключений обойтись — ну так мы в таком случае ничего не теряем, значит
TKC> ни одного throw в коде и не будет.
так ведь такую логику еще спроектировать надо. если думать заранее: а вот что произойдет если вызывающий
код забудет проверить ошибку? какие данные мы должны будем ему вернуть, чтобы обойтись без критических последстй?

ТКС>Конкретно с комментарием лично я бы оставил как есть. Ну то есть если встретили одинарный /*

TKC> — выкидываем все до конца (хотя тут по уму все равно надо бы возвращать ошибку),
это понятно. что делать с вложенными комментариями тоже понятно. в крайнем случае можно подддержать вложенность, хоть и противоречит стадарту, ну и что? это же не баг, это фича. а вот если это printf(".../*......*/[EOF]. тут как бы не совсем понятно что делать с незакрытой строкой. оставлять как есть? про #define я молчу. _корректно_ удалить комментарии без поддержки #define нельзя, ибо можно так извратиться, что и код будет следовать стандарту, и в нем незакрытые скобки будут, которые удаляются сишным препроцессором, но о которых спотыкаемся мы.

про то, что функции необхходим еще один аргумент — ссылка на стандарт я молчу. старндарты они сильно разные. по одному стандарту /**/ замееяется пробелом, по другому просто удаляется. какому стандарту следовать, если он явно не оговорен в ТЗ?

ТКС> Ну это всего лишь не полностью сформулированное ТЗ. В жизни у меня таких почти не бывает,

TKC> потому что я либо начинаю пытать заказчика, пока не выложит, для чего ему это надо,
ну в даннном случае это было задание не сколько на программирование, сколько на знание как нужно правильно программировать. т.е. чем больше "граблей" найдет в задании человек, тем он круче. из того что нашел я:
1) как возвращать ошибку?
2) нам что всерьез предлагают писать препроцессор?!!!
3) какой стандарт имеется ввиду?!

показательно, что программу я таки не написал. вернее написал, но в ней была пара багов. но оффер таки получил и программу зачли. а вот знакомый индус получивший тоже самое задание убеждал меня, что он его _решил_ и решил его правильно. оффера он не получил я попросил его скинуть программу на мыло. ну что? программа как программа. работает, не падает. про вложенные комменты, про пунткы 1, 2, 3 она ес-но не знает, но явных багов в ней нет.

вот и выходит, что я знаю как правильно программировать, но сам программировать не умею. а он умеет, но не знает.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[20]: # еще раз: сколько стоит одна строка кода на си?
От: gear nuke  
Дата: 19.12.09 01:28
Оценка:
Здравствуйте, eagersh, Вы писали:

E>Но С++ не все так плохо в системном програмировании.Можно програмировать на нем тоже, но правда с ограничениями.Надо хорошо понимать эти ограничения, и как их обходить. Microsoft например сейчас широко использует кернел API — WDF которая написанна на С++.Но правда Microsoft все еще не рекомендует использовать С++ для написания драйверов. Их понять можно, так как драйвера фактически часть OS со всеми вытекающими последствиями.


Я довольно неплохо знаю ситуацию в default OS, основная проблема — MS до сих пор не удосужились сделать C++ runtime.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[14]: # еще раз: сколько стоит одна строка кода на си?
От: gear nuke  
Дата: 19.12.09 01:49
Оценка:
Здравствуйте, мыщъх, Вы писали:

М>имеется ввиду "выделение памяти под массив". а если массив еще не дай бог и иницилизированный, то это вообще капец в случае со стеком. самый классический пример: char buf[]="hello, world!\n".


Если к этому коду дописать static, он станет медленнее, поскольку инициализация будет в обоих случаях. Если добавить еще и const — будет сравнение разных сущностей.

М> менее классический, но так же встречающийся это int matrix[x][y][z] = ... ;


М>но даже если массив не иницилизирован. объявляя в статике int buf[xxl] мы ничего не теряем. даже память не коммитим. вот как воспользуемся буфером (если вообще воспользуемся) так ось и закоммитит.


М> если же массив локальный ОС выделяет память при входе в функцию. и эта функция пробегается по каждой странице массива даже если память была выделена ранее (компилер же не знает была выделеена память или нет). допустим, у нас массив на 400 кб. тогда компилятор воткнет скрытый цикл на сотню итераций. если цикл функцией реально используется хотя бы на 30% — потери производительности невелики


Да тут точно такой же механизм коммита работает, как и при подкачке секций PE со статиками. А нет, пожалуй, вру. Стек менее вероятно будет позже вытеснен в своп.

М>, но что делать, если массив размером с максимально допустимую длину некой структуры (строки), а в рельности функция работает намного с более короткими строками?


Не уверен, что понял о чем речь, но наверное надо будет почитать о менеджменте памяти, например lookaside lists?

М>ЗЫ. я ж сказал "иногда" (см. выделенное). в _общем_ случае различие в производительности действительно скорее всего не будет заметно.


Иногда самая быстрая программа = которая ничего не делает.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[15]: # еще раз: сколько стоит одна строка кода на си?
От: мыщъх США http://nezumi-lab.org
Дата: 19.12.09 02:56
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, мыщъх, Вы писали:


М>>имеется ввиду "выделение памяти под массив". а если массив еще не дай бог и иницилизированный, то это вообще капец в случае со стеком. самый классический пример: char buf[]="hello, world!\n".


GN>Если к этому коду дописать static, он станет медленнее, поскольку инициализация будет в обоих случаях.

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

foo(int a)
{
char x[]="0123456789ABCDEF";
return x[a & (0x10-1)];
}

пример жизненный. надуманным его назвать трудно. а теперь поставьте static и посмотрите что из этого выйдет. производительность возрастет в разы. если не в 6 раз, то раз в 3 точно с учетом всех прочих накладных расходов. а ведь у нас массив всего из 16 байт...

М>> если же массив локальный ОС выделяет память при входе в функцию. и эта функция пробегается по каждой странице массива даже если память была выделена ранее (компилер же не знает была выделеена память или нет). допустим, у нас массив на 400 кб. тогда компилятор воткнет скрытый цикл на сотню итераций. если цикл функцией реально используется хотя бы на 30% — потери производительности невелики


GN>Да тут точно такой же механизм коммита работает, как и при подкачке секций PE со статиками. А нет, пожалуй, вру. Стек менее вероятно будет позже вытеснен в своп.


при чем тут подкачка?! погуглите page guard. узнаете много нового. а так же объявите массив больше 4 кб в стеке и посмотрите что сделает компилятор. стек не является памятью с произвольным доступом. он растет вверх и память под него выделяется постепенно. постранично. поэтому, если мы выделяем массив из 8 кб памяти, мы вынуждены совершить одно обращение сначала к последней странице, а потом к первой. если обратимся сразу к первой — приложение рухнет. можете проверить на naked функциях, куда компилятор ничего не вставляет. поэтому, если у нас массив из N страниц, где N намного больше 1, то накладные расходы на пробег по всем страницам (при каждом вызове функции!) становятся ощутимыми.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[16]: # еще раз: сколько стоит одна строка кода на си?
От: gear nuke  
Дата: 19.12.09 06:22
Оценка: 5 (1)
Здравствуйте, мыщъх, Вы писали:
.
М>с какого это перепугу при static у нас появится что либо? компилятор в студию. даже с выключенной оптимизацией при static оно будет в сегменте данных, откуда и загрузится с диска, а в стеке оно будет копироваться из сегмента данных в стек уже в рантайме при каждом вызове функции, что сильно тормозно. рассмотрим для примера функцию, которая превращает число из 0..F в символ.

М>foo(int a)

М>{
М>char x[]="0123456789ABCDEF";
М>return x[a & (0x10-1)];
М>}

М>пример жизненный. надуманным его назвать трудно.


Этот пример — поросту не в тему, зачем начинаешь юлить? Напомню изначальный контекст:

почему статические массивы иногда на порядок быстрее, а то и на два. ну а то, что они потоконебезопасны — это заблуждение.)


Вот простейший массив из одного элемента, инициализаруемый произвольным значением:
?foo0@@YGXH@Z PROC                    ; foo0, COMDAT

; 172  : {

    push    ebp
    mov    ebp, esp
    push    ecx

; 173  :   int x[1] = { f() };

    call    ?f@@YGHXZ                ; f
    mov    DWORD PTR _x$[ebp], eax

; 174  : }

    mov    esp, ebp
    pop    ebp
    ret    4
?foo0@@YGXH@Z ENDP                    ; foo0


?foo1@@YGXH@Z PROC                    ; foo1, COMDAT

; 178  : {

    push    ebp
    mov    ebp, esp

; 179  :   static int x[1] = { f() };

    mov    eax, DWORD PTR ?$S1@?1??foo1@@YGXH@Z@4IA
    and    eax, 1
    jne    SHORT $LN2@foo1
    mov    ecx, DWORD PTR ?$S1@?1??foo1@@YGXH@Z@4IA
    or    ecx, 1
    mov    DWORD PTR ?$S1@?1??foo1@@YGXH@Z@4IA, ecx
    call    ?f@@YGHXZ                ; f
    mov    DWORD PTR ?x@?1??foo1@@YGXH@Z@4PAHA, eax
$LN2@foo1:

; 180  : }

    pop    ebp
    ret    4
?foo1@@YGXH@Z ENDP                    ; foo1
Он заодно показывет неверность твоего второго утверждения.

М> а теперь поставьте static и посмотрите что из этого выйдет. производительность возрастет в разы.


Я тоже могу привести какой-то частный случай, и начать делать из него обобщённые выводы. Но не буду.

М>при чем тут подкачка?!


Подкачка при том, что изменённые данные в статическом массиве уйдут на диск, при нехватке физической памяти. Стек, как постоянно используемые данные — менее вероятный кандидат для этого.

М> погуглите page guard. узнаете много нового.


Не пойму, каким боком тут сторожевые страницы. Ну, первый раз будет инициализация, как и подкачка страницы PE имиджа. Счёт 1:1. А потом программа будет работать дальше, и счет постепенно изменится не в пользу статиков. Обрати внимание, я не пишу константных статиков, как и ты!

М> а так же объявите массив больше 4 кб в стеке и посмотрите что сделает компилятор. стек не является памятью с произвольным доступом.


О, это такая память, к которой можно обращаться только командами push и pop?

М> он растет вверх и память под него выделяется постепенно.


А че не в лево то? Может быть в сторону младших адресов? Это не сарказм, а иллюстрация что лучше учить сначала — асм, или С.

М> постранично. поэтому, если мы выделяем массив из 8 кб памяти, мы вынуждены совершить одно обращение сначала к последней странице, а потом к первой. если обратимся сразу к первой — приложение рухнет. можете проверить на naked функциях, куда компилятор ничего не вставляет. поэтому, если у нас массив из N страниц, где N намного больше 1, то накладные расходы на пробег по всем страницам (при каждом вызове функции!) становятся ощутимыми.


Ты, похоже, так ничего и не понял стех пор, как лет 5 назад на wasm.ru твой memcpy проиграл коду из мануала (!) по процессору в несколько раз.

Эти обращения играют роль prefetch и подгружают данные в кеш.

А если у нас N страниц в секции PE имиджа — ОС не сможет его загрузить.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[17]: # еще раз: сколько стоит одна строка кода на си?
От: legogogo  
Дата: 19.12.09 08:15
Оценка: 1 (1)
Здравствуйте, gear nuke, Вы писали:

GN>А че не в лево то? Может быть в сторону младших адресов? Это не сарказм, а иллюстрация что лучше учить сначала — асм, или С.


Если не ошибаюсь, в старых Unux стек рос вообще вниз на встречу text segment (блоку данных) до разделения стека и кода по разным сегментам и точка где они должны встретится называлась break или break point.
Компьютер — это конечный автомат. Потоковое программирование нужно тем, кто не умеет программировать конечные автоматы (c) Алан Кокс
Re[17]: # еще раз: сколько стоит одна строка кода на си?
От: мыщъх США http://nezumi-lab.org
Дата: 19.12.09 08:24
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Этот пример — поросту не в тему, зачем начинаешь юлить? Напомню изначальный контекст:

GN>

почему статические массивы иногда на порядок быстрее, а то и на два. ну а то, что они потоконебезопасны — это заблуждение.)

GN>Вот простейший массив из одного элемента, инициализаруемый произвольным значением:
выше было написано _иногда_
а быстрее они по следующим причинам:
1) необходимость иницилизации локального массива при каждом вызове функции;

2) необходимость "пробежки" по каждой странице выделенной памяти в стеке при каждом вызове функции;


GN>; 173 : int x[1] = { f() };

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

GN>Я тоже могу привести какой-то частный случай, и начать делать из него обобщённые выводы. Но не буду.

М>>при чем тут подкачка?!
GN> Подкачка при том, что изменённые данные в статическом массиве уйдут на диск, при нехватке физической памяти.
GN> Стек, как постоянно используемые данные — менее вероятный кандидат для этого.
гражданин, это в сегмнте данных данные есть изначально. в стек они попадают без всякой магии путем простого копирования. другой вопрос, что компилятор может расположить данные не в стеке, а на непосредственных значениях, копируя их инструкцией mov, но тогда у нас резко возрастает размер кода.


М>> погуглите page guard. узнаете много нового.

GN>Не пойму, каким боком тут сторожевые страницы. Ну, первый раз будет инициализация,
блин, да не первый раз она будет. компилятор вставляет в начало функции код, "пробегающий" массив при _каждом_ вызове функции.

М>> а так же объявите массив больше 4 кб в стеке и посмотрите что сделает компилятор. стек не является памятью с произвольным доступом.

GN>О, это такая память, к которой можно обращаться только командами push и pop?
если вы знаете асм, то напишите:
sub esp, 4*1024*69
mov eax, [esp]

и получите исключение. потому как память не выделена. а чтобы выделить ее надо запрашивать страница за страницей. и никак не более страницы за раз.

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

GN>Ты, похоже, так ничего и не понял стех пор, как лет 5 назад на wasm.ru твой memcpy проиграл коду из мануала (!) по процессору в несколько раз.

GN>Эти обращения играют роль prefetch и подгружают данные в кеш.
ваша гипотеза неправильная. гуглите описание функции chkstk, которую вставляет в код ms vc.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Re[13]: # еще раз: сколько стоит одна строка кода на си?
От: gear nuke  
Дата: 19.12.09 09:14
Оценка:
Здравствуйте, eagersh, Вы писали:

E>Это ты не в теме.Попробуй написать драйвер на С++ для Windows. После этого твои прямые руки станут кривыми

E>Можешь также почитать вот это.
E>http://www.microsoft.com/whdc/driver/kernel/KMcode.mspx

А еще вот это http://security.ti.bfh.ch/projects/lugh.html
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.