All streams
Search
Write a publication
Pull to refresh
20
0.1

Программист

Send message
Деструкторы нужны НЕ для того, чтобы вызвать в них delete. Например, сокеты я тоже в деструкторах закрываю. И с файлов блокировку снимаю. И с тех же мьютексов. Я не знаю, есть ли в C# деструкторы, если нет, то пичалька, придётся каждый раз в блок finally писать код, который можно один раз в деструктор написать.
Мне не нужно ВСЕГДА передавать классы по ссылке, потому что в некоторых случаях эффективнее по значению. Что? В шарпике тоже можно по значению передавать, но только структуры? А вот в плюсиках можно передавать так, как хочешь. А ещё можно передавать по значению, но при этом копирования объекта не будет, потому что изначально будет использоваться тот объект, который потом вернётся из функции. Да, С++ и так может, потому и компилируется код долго, что он много чего может.
Я окидываю код взглядом сотни, а то и тысячи раз. Не ради ошибок работы с памятью — этот класс ошибок у меня практически устранён на уровне архитектуры приложений. Я в принципе стараюсь не писать такой код, в котором могут быть ошибки работы с памятью. То же касается и ошибок переполнения буфера.
Анализаторы кода запускаю раз-два в месяц (не считая того анализа, на который способен компилятор при каждой компиляции). Логические ошибки обнаруживаются периодически. Неправильная инициализация обнаруживается. Дублирующиеся и не эффективные сравнения обнаруживаются. С памятью пока ничего связанного не обнаруживалось.
У Макконелла по этому поводу очень хорошо было написано: Выделил память, сразу же напиши код её освобождения. Всё проблема решена.
Я себя ни в чём не ограничиваю! Благодаря stl и прочим контейнерам отпадает необходимость в ручном выделении/удалении памяти для коллекций. Штучные объекты создаются менеджерами объектов(как раз те редкие файлы с new/delete), но это сделано не ради отказа от new, а из-за фабрик полиморфных объектов. Кстати, есть множественное и пирамидальное наследование, но проблем с ним тоже нет. Это я вспомнил ещё один популярный камень в огороде С++.
Нет почти по всем озвученным тезисам.
Начну с конца.
Я не называл студентами и второстепенными тех, кто не хочет писать конструкторы, я называл студентами и второстепенными программистами тех, кто не может поставить символ & и делает из этого трагедию. Впрочем, я не называл никого второстепенными и студентами называл не в обидном смысле слова, а в смысле временного отсутствия опыта.
Конструкторы и деструкторы нужны не только и не столько для освобождения памяти. Скажу больше, сейчас у меня в проекте около полутора тысяч файлов, при этом new и delete используются буквально в десятке из них. Вызывать вручную delete? Ну написал его один раз в деструкторе — руки не отвалятся.
Если не выделять память через malloc/new, а использовать контейнеры, то писать конструкторы копирования(а ещё и присваивания!) не нужно. Если следовать RAII, то и деструкторы не всегда нужны, по крайней мере delete в них писать точно не придётся.
Выход за границы массива проверяются в дебаге и в релизном коде уже в принципе не должно быть выхода за границы (я метатель). При желании, можно проверять выход за границы массива и в релизном коде (at вместо []). Это С++, тут можно практически всё, было бы желание.
В современном программировании под «ручным управлением памяти» подразумевается, что программист в любой момент времени знает, существует ли объект или нет и знает, когда именно этот объект будет уничтожен. Может сам выбрать для этого момент, чтобы был наименьший удар по производительности. Может вообще не разрушать объект. А может положиться на RAII и вообще быть не в курсе, что такое ручное управление.
Чуточку же.)
Я вообще только про Windows выше написал, так как не знаю тонкостей работы менеджера памяти linux…

Перефразирую, чтобы не было разночтений:
В зависимости от реализации менеджера памяти на конкретной версии ОС получение объекта из пула может быть эффективнее получения памяти под объект из менеджера памяти.

Отсюда возвращаемся к лейтмотиву всей трилогии статей и всех комментариев к ним: не посмотрев в профайлер вообще говорить не о чем.
Тут вы чуточку не правы. malloc/new требуют перехода из user-mode в kernel-mode и из-за этого производительность страдает. Насколько страдает зависит от количества миллионов аллокаций (в секунду). Для new специфические аллокаторы и память могут гораздо эффективнее использовать. Но против malloc не приёма, если нет другого malloc.)
Так вы же читерите там! Ищете словоформы по хэшам бинарным поиском, а надо строго линейным! Дважды, чтобы наверняка! Иначе не честно.
Если вы теряете ВСЮ производительность из-за подсчёта ссылок, то вы явно делаете что-то не так. Самый простой вариант — сделать интрузивный подсчёт ссылок, тогда он получается практически бесплатный, потому что счётчик находится в объекте, а не хранится где-то отдельно и нет лишней беготни по памяти — минимум кэш миссов.
Ничего личного, но в 2006 году знаний С++ у вас было меньше, чем сейчас, поэтому что вы там натворили — одному Богу известно. А говнокод может тормозить по любому поводу.
Без иронии.
Чудная обезьяна целую неделю страдала-голодала, но продолжала бросать палку-копалку в пробегающих мимо антилоп. Другие обезьяны над ней смеялись, ведь палка-копалка нужна, чтобы сбивать бананы, а не антилоп. А она продолжала бросать, пока не научилась попадать в цель и жрать питательное мясо. А другие обезьяны продолжали над ней смеяться и стали зваться вегетерианцами.

Вот вы реально проблемы на пустом месте придумываете. Студенты косячат и ругают указатели и прочее, но это совсем не проблема. Опытный программист просто физически не сможет написать код с вышеозвученными проблемами, потому что подсознание спать не даст, пока не исправишь эту ошибку. Про codestyle я написал не ради красивого словца, а по делу. Если чётко сказано, что входные параметры должны быть ко константной ссылке, а выходные по ссылке или указателю, то косяк просто не пройдёт code review. Не говоря о том, что в блокнотах кодят только обезьяны и любая современная IDE обнаруживает большинство ошибок (вы ведь читаете предупреждения компилятора?), и ещё больше ошибок отлавливаются специальными утилитами (блюющим единорогом) и профайлером.

Но уровень вхождения в C# несколько ниже, с этим соглашусь. Можно говнокодить не отстреливая ноги из верёвки.
Тут сортировка меняется на обратную, так что циклы кружатся не в холостую. С точки зрения пузырька — как раз самый плохой случай. Хотя, для него любой случай — самый плохой.
Достаточно пару сотен раз обжечься и проблема забытой ссылки пропадает сама собой. Со мной в последний раз это случилось четыре года назад. Вернее, шесть лет назад, но два года эта ошибка не проявляла себя. Вектор передавался по значению, но почти всегда был из малого числа элементов и на производительности заметно не сказывалось. Лишь когда при определённом использовании размер увеличился до нескольких сотен элементов и производительность экспоненциально падать начинала (столь глупая ошибка была в рекурсивной функции), то косяк обнаружился. И сразу же был исправлен.
Столь громко осуждаемые и обсуждаемые ошибки с указателями, ссылками и прочим — по большей части удел студентов. Спустя несколько лет практики их уже на уровне инстинктов не допускаешь.А ещё помогает RAII и следование codestyle.
По поводу оверхеда умных указателей — в шарпе-то этот оверхед есть всегда и везде (unboxed не учитываем), а в Сишке только там, где пожелает программист.
Вот и я о том же! Сперва один сравнивает языки неадекватным способом. Затем другой, пытается доказать неправоту первого. При этом оба не знают тонкостей «противного» им языка.
Допустим, что сравниваем производительность пузырька, мне не жалко. Но! Программу на С++ должен писать хорошо разбирающийся в С++ программист, а на C# — разбирающийся в C#. Без обид, но С++ вы если и знаете, то не сильно плотно. А я не смогу написать максимально эффективно на C#, только если случайно совпадёт. Т.е. все эти три статьи о «сравнении» языков — пердёж в лужу (извините, не ругайте).

C-style нужно делать через указатели. Почти 100% гарантия того, что будет самый эффективный вариант. Если компилятор индексированный доступ сам не смог в указатели переделать.
> Те кто знают (или думают что знают) C++
Классно вы себя приложили.) Различие между [] и at именно в том, что проверка выхода за границы в релизе есть только у метода at. Встречал кривые реализации, где скобки даже в дебаге границы не проверяли. Именно поэтому между массивом и vector в релизе разница околонулевая (на усмотрение компилятора).
> Поэтому vector использует динамическую память для хранения массива и должен честно проверять выход за границы.
В релизе vector[] НЕ проверяет выход за границы. Если хочется «честногО» сравнения, используйте vector.at()

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

Типовой код. Бабл сорт. Типовой. Большая вероятность… Какой смысл сравнивать производительность типовых лабораторных работ первокурсников?
Да, в актуальной версии разницы во времени доступа нет — всё ОК.
Очень мило среди пузырьков смотрится результат std::sort.
Внукам будем рассказывать, что в стародавние времена читать новости в интернетах можно было на слабеньких четырёх-ядерных компьютерах с 8 гигабайтами оперативки и одной дискретной видеокартой и практически без тормозов, а они будут улыбаться и считать нас старыми пердунами, которые опять выдумывают какие-то небылицы.
Не углядел ссылку на тестовые файлы…
Не понимаю, каким таким образом удалось получить такую разницу между std::vector и HeapArray. Если в векторе доступ был через оператор индексирования, то разницы с простым массивом быть в принципе не могло (мы же говорим о release версии). Вообще, между всеми четырьмя типами С++ массивов не должно было быть принципиальной разницы, учитывая размер массива. Такое чувство, что разница в результатах обусловлена кэш-миссами и вообще работой с памятью. Прям хочется повторить со всеми четырьмя массивами, но нужны исходники.
> std::wcout<<«Bot: Не распознана ключевая последовательность!»

Уточка говорит: «Зря-зря».

По коду ничего говорить не буду, но дам пару рекомендаций для последующей реализации:
1. В юникод потоки следует посылать юникод строки. Но сперва нужно подключить к ним русскую локаль, тогда можно на человеческом языке писать, без 866 кодировки.
2. Перед сохранением конвертируй строки в utf8; при чтении — обратно в юникод.
3. Про ASCII строки пора бы уже начать забывать.
Напряг, только если не использовать CMS. При использовании любой CMS это уже не напряг, а вопрос целесообразности. Если css большой и используется в куче файлов, то лучше уж один раз его загрузить и дальше он будет браться из кэша, чем каждый раз по новой бОльший html файл скачивать. Так что тут надо смотреть по ситуации. Ну и по возможностям CMS.
А если верстать вручную, то тут однозначно отдельный файл. Или однозначно inline, если страниц одна-две. Всё ОЧЕНЬ однозначно.)
Давно собираюсь написать «свой» плеер. Из существующих для Windows меня устроил только 1by1, но он иногда папки проскакивает, да и кое-какого функционала нет в нём. Собирался использовать библиотеку bass (её уже приходилось использовать, а производительность меня мало волнует в контексте плеера), но почитаю и про упомянутые вами библиотеки. Мне нужно лишь mp3 и ogg.

А ваша книжка на русском будет издаваться? С удовольствием бы почитал. В ней есть что-нибудь про трекерную музыку под андроид?
Можете даже не сомневаться, что чисто софтверный. У меня на мыльнице альтернативная прошивка, которая включается только если SD-карточка в положении lock. Блокирую карточку и могу сохранять raw, помимо jpg и прочее. Т.е. это 100% не аппаратный замок.

Information

Rating
3,445-th
Location
Новосибирская обл., Россия
Registered
Activity