Собрался наконец написать. Минусов мне за эти тезисы поставят, это уж точно. Ну
что же — к счастью, я уже не в том возрасте, когда падение или рост рейтинга
могут серьезно повлиять на самочувствие.
Итак...
Когда компьютеры были большими, память у них была маленькой и
быстродействие тоже. И поэтому гуру от этих ЭВМ ничего, кроме ассемблера
(автокода, по-тогдашнему) и не признавали. А на нас, всяких там алгольщиков или
фортранщиков, смотрели свысока — писать , мол, эффективные программы не умеют,
только зря машинное время расходуют. Мы, конечно, с ними на словах не
соглашались и всякие аргументы приводили, но в глубине души их правоту, пожалуй,
признавали.
И действительно, как было не признать! Пока программа небольшая и в память
помещается — ладно, живите и радуйтесь! Ну а как побольше стала ? Тут-то и
придется признать свое бессилие. А гуру, им что, всегда что-нибудь придумают.
Кто-нибудь из нынешнего поколения слышал про "самоубийство программ" ? Нет, это
не стирание EXE-файла во время его работы. Это когда программа во время своей
работы использует память, занятую своими командами (которые уже отработали и
больше не потребуются) под свои данные. Вряд ли кому-нибудь придется этим сейчас
заниматься, и слава богу. А вот когда у Вас всего 18 Кбайт, то и таким не
пренебрегали.
Потом компьютеры стали больше. И в размерах (один мой знакомый, рост у
него 1.80, любит рассказывать, как он в процессор некоторой машины входил не
наклоняясь , но все же и память с быстродействием тоже росли. Вспоминаю
сейчас ЕС-1022. Памяти там было уже 512 Кбайт, правда, сотню из них занимала ОС.
Остальные 400 делились между 3-4 одновременно работавшими программами разных
пользователей. Так что на тех, кто заказывал больше 200 Кбайт, на ВЦ смотрели
довольно косо — за наш счет ведь! И правильно смотрели — нечего тут жировать!
Компилятор с Фортрана на 96 КБайтах работал, c PL/1 — даже на 64 Кбайтах (до сих
пор не знаю, почему — PL/1 сложнее Фортрана), линкеру тоже 96 Кбайт хватало, а
тебе так 200 надо ? Иди-ка, батенька, да перепиши свою программу как следует. До
сих пор помню, как потратил несколько часов, пытаясь написать вычисление
произведения трех матриц без промежуточной матрицы (было это на заре моей
карьеры, а я ведь химик .И студента своего, который без надобности
транспонировал матрицу, заведя еще одну, так отругал, что он долго это помнил :-
)
В общем, если говорить серьезнее, эффективность у нас была всегда на
первом плане. Не как-нибудь написать, а наиболее эффективным способом,
не любой алгоритм использовать, а лучший для этого случая. На этом мы
прочно стояли.
Поймите меня правильно. Это вовсе не значит, что мы оптимизировали
все и вся. Код, который работает 0.1 сек и занимает 100 байт, никто
не оптимизировал. И то, что оптимизировать нужно самые внутренние
циклы, мы прекрасно знали. Не об этом речь. А о том, что при написании
программ была определенная культура, требовавшая памятью не сорить
без надобности, первый попавшийся алгоритм не применять, а искать хороший,
ну и т.д.
Потом компьютеры стали меньше. И по размерам, и по быстродействию и
памяти тоже. Не потому, что большие исчезли, а потому, что малые
появились. Их так и называли — мини-ЭВМ. СМ-4, к примеру. Памяти у нее
было поменьше, быстродействие похуже, чем у той же ЕС-1022, зато у нее
было неоспоримое преимущество — она была моя! Никакого тебе ВЦ с десятком
конкурентов, никаких "Правил работы на ВЦ ... института", правила такие,
какие я хочу. Все это не могло не радовать, но все же уменьшение
памяти и быстродействия огорчало и тем более заставляло бороться
за эффективность. Первая моя серьезная работа на СМ-4 — адаптировать к
ней программу, которая на ЕС занимала 220 Кбайт, а здесь их всего 256.
Когда я понял, как ее в свободные 200 уложить — выяснилось, что понял
я неправильно, и для кода я могу рассчитывать только на 64 Кбайта, а
остальную память только под данные можно использовать. Вот тут-то я
и покрутился. Вы никогда не делали оверлейные структуры 9-го уровня ?
Даже не знаете, что это такое ? Ну и прекрасно, и не надо вам знать
Потом машины стали совсем маленькими, а быстродействие и память
уменьшились до неприличия. Проще говоря, пересел я на Ямаху-1. Память 64 Кбайта,
частота 2MHz, флоппи-диск — живи и радуйся! В общем, 8-битная машина. И вот на
этой машине я увидел чудо.
Чудо называлось Turbo Pascal 1.0. Сказать, что он меня поразил — не то
слово. И не меня только. Все, кто до этого Ямаху не видел (а их в Омск
очень немного попало тогда) и кому я о нем говорил, отвечали мне одинаково-
такого не может быть!
В 64 Кбайтах размещались
MSX-DOS, точнее , ее резидентная часть — несколько Кбайт
сам компилятор Turbo Pascal. Сидел резидентно в памяти.
редактор текста Turbo Pascal, вполне приличный по тому времени.
исходный текст программы, набранный в этом редакторе.
рабочая программа (машинные команды). Да-да, я не оговорился.В обычном
режиме компиляции программа размещалась в ОП и на диск не записывалась. И
не думайте, что это какой-то паршивый интерпретатор был, нет, самый
настоящий компилятор. Чуть позже (я уже в университете работал) был
у нас класс "Ямаха-2", память там была уже 128 Кбайт, а дисков на рабочих
станциях не было. Так вот. половину из этих 128 Кбайт мы отводили
под электронный диск, туда в начале занятия записывали Turbo Pascal,
а в конце с него переписывали на машину преподавателя .pas файлы студента.
Остановимся на минуту и вдумаемся. Итак, все это помещалось в 64 Кбайта.
Можно было, значит, написать это так, чтобы помещалось. Если, конечно,
эффективно написать. И работало это с вполне по тем временам приличной
скоростью. Не хуже, чем на СМ-4, кстати сказать. Даже лучше.
А потом компьютеры, хоть и не меньше и не больше по размерам стали, начали
резко увеличивать свою память и быстродействие. Сейчас любят вспоминать
пророчество Б.Гейтса — дескать, 256 Кбайт всем хватит. Ну, во-первых,
не думаю, что они имел в виду, что это навсегда. Во-вторых, никто,
в т.ч. Гейтс, в то время не понимал, что на свет явился не расширенный
калькулятор для научных лабораторий, а нечто такое, что перевернет
мир. А 256 Кбайт по тем временам — очень даже много. Настолько много,
что для большинства тогдашних задач это даже и не требовалось. Впрочем,
довольно скоро от этих 256 к 640 перебрались, на этом значении, правда,
надолго застряли.
Вот тут первые шаги в сторону пренебрежения оптимальностью уже и начались.
Действительно, на машине 600 Кбайт свободно, машина однопрограммная,
конкурентов нет, зачем мне пытаться программу в 100 Кбайт уложить ,если можно
все 500 спокойно использовать. Впрочем, память памятью, а есть еще и
быстродействие. Оно было еще очень маленьким, так что хотя бы в этом
плане писать все же приходилось эффективно, выжимать из машины все, что можно.
Так что писать старались все же эффективно, хотя десятком, а то и сотней
лишних Кбайт уже не мелочились.
Что было дальше — все знают. Память и быстродействие росли, эффективность
падала так же быстро, как те росли. Выяснилось, что и 1 Мбайта мало для
программы, предыдущая версия которой вполне 256 К было достаточно, да что там
1Мбайта, и 2 мало, и 16 мало, подайте 32, нет, 32 тоже мало, без 64 не
обойдемся.
Вот вам 2 классических примера.
Конечно, Object Pascal не Turbo Pascal, а Delphi 7 не Turbo Pascal 1.0.
Но, положа руку на сердце — неужели язык в 1000 раз усложнился ? Ну в 5-10
раз сложнее стал, не спорю (я имею в виду в плане написания собственно
компилятора, а не IDE, отладчика и т.д.). А раз так, то для компиляции
консольных приложений компилятор командной строки-то уж должен в 640 Кбайт
уложиться ? Дудки вам, а не 640 Кбайт. В 640 Кбайт сейчас умеют только "Hello,
World" укладывать! Пока несколько десятков Мбайт не будет, и не подходите.
Другой пример — сама Windows. Я прекрасно понимаю, что Windows NT 4 и
Windows XP — не совсем одно и то же. Но та на 8 Мбайтах работала, а эта от
128 нос воротит, подавай ей 256. А ядро, вообще говоря, претерпело не такие
уж большие изменения.
Почему же так произошло? На мой взгляд, просто потому, что требованию
эффективности просто перестали уделять нужное внимание. Если памяти много —
чего ее жалеть, зачем экономить? Какой смысл бороться за то, чтобы твоя
программа занимала 8 Мбайт, если можно взять 64 ? Даже, пожалуй, наоборот-
увидят, что твоя программа меньше памяти занимает, чем у конкурента — ну
и решат, что та более крутая
Разумеется, эффективности внимание перестали уделять не везде. Для тех
программ, которые и сейчас работают на пределе возможностей машины, за
эффективность по-прежнему борются, да еще как, иначе ведь работать вообще
не будет. Ну а там, где для предела далеко — чего это мы будем лишний
десяток Мбайт экономить ? Пусть пользователь память докупит, она нынче
дешевая!
Вспоминаю один случай из своей практики. Вел я тогда кружок в средней
школе,хорошие ребята попались, большинство из них потом наш матфак закончили. В
DOS на Turbo Pascal, лет 10 назад это было. И вот дал я одниу мальчику
упражнение, сделал он его, показал мне, посмотрел я , похвалил и добавил :"А
теперь, Илья, выкинь отсюда этот массив. Он здесь совсем не нужен, и без него
даже лучше получится". До сих пор помню тот взгляд, которым он меня одарил
Если кто-то думает, что моей целью было 200 байт сэкономить — ничего Вы
из моих рассуждений не поняли. Моей целью было научить его грамотно писать
программы, делать как следует, а не так, как получится. Не реализовать первую
пришедшую в голову идею, а подумать, нельзя ли здесь лучше сделать! Потому что
если я сейчас это пропущу — он и дальше будет так же делать, тройные циклы
писать там, где двойных хватит и лишние массивы без надобности заводить.
Меня тут некоторые уже обвиняли в "наездах" на C# и .Net. Вообще-то
я такое понятие "наезд" — не признаю. Если к любимой системе программирования,
компилятору и т.д. подходить с позиций "В России нет еще пока команды лучше
Спартака" — тогда, конечно, всякая критика левого крайнего Спартака есть явный
наезд . Если же подходить к этому вопросу объективно, скажем, с позиций
человека, который вообще ни за одну команду не болеет или болеет за Реал-Мадрид,
то сравнение левого крайнего Спартака и левого крайнего ЦСКА есть дело вполне
разумное, и если вывод будет не в пользу спартаковца — ничего страшного тут нет,
что же поделаешь... Другого левого крайнего искать надо, а может, стоит из
ЦСКА его переманить .
Так что в том. что примеры я буду приводить именно из области .Net — не
есть наезд на нее. Просто ИМХО она наиболее ярким образом характеризует то, о
чем я пишу.
Вот простой пример. Ставя свои эксперименты, обнаружил я , что в
библиотеке .Net не имеется способа получить список файлов каталога без того,
чтобы не прочитать его полностью.
Чтобы не было неясностей — класс DirectoryInfo как он есть, не позволяет.
То, что можно самому написать, с использованием InterOp — я это и до
постинга вполне понимал.
Мне это показалось странным, и я решил вопрос в форуме задать. В общем,
объяснили мне то, что я и так знал, и подтвердили , что без InterOp это
не делается, а с ним — великолепно.
Поясню, в чем проблема здесь. С помощью Win32 функций можно записи
о файлах по одной получать. Времени на чтение всего каталога это
никак не уменьшит, это вообще не от моей программы, а от драйвера
ФС зависит, а вот памяти мне в Win32 почти совсем не надо — одна
структура WIN32_FIND_DATA на все файлы, хоть 100 их будет, хоть
миллион. А класс DirectoryInfo предлагает считать весь каталог
в оперативную память (массив FileInfo), а потом уж из него брать.
Проверил я этот DirectoryInfo на имеющемся у меня каталоге в
100,000 файлов. Работало это все 1 минуту (неудивительно, и Win32 программа
не меньше бы потребовала, FAR, к примеру, именно столько и требует)
и заняло по Task Manager 57 Мбайт.
Ну ладно, я не вчера родился, и как это на Win32 делается — еще лет 10
назад знал Так что такое решение, приведись мне это в реальной программе
писать, меня вряд ли бы устроило, и что-нибудь бы придумал или вопрос бы задал.
А как же будут делать те, кто школу более или менее эффективного (в этом
плане, только в этом плане!) программирования в Win32 не прошел, а сразу за .Net
взялся ?
Вот ведь что мне Sinclair советует
Цитирую
> То, что ты умеешь делать на плюсах, в рамках дотнета ты делать не сможешь.
Некоторые концепции могут быть переиспользованы, но в целом легче изучать
дотнет с нуля.
Не обо мне сейчас речь. Но вот те, кто начнет именно с нуля, вполне
могут принять как принцип то, что если нужно что-то такого рода получить —
получайте всю коллекцию, и не мучайтесь, потом в ней разберетесь и нужное
найдете. Стиль мышления такой прививается, понимаете? Как вполне нормальный.
Да и не скрывают это адепты. Вот, например,
>А производительность и не должна быть на первом месте. Она должна быть
достаточной. А на первом месте должны быть удобство и простота.
Я не против удобства и простоты. Я за. А вот что такое "достаточной" —
извольте объяснить. Если машина однопрограммная — тогда, конечно, достаточно —
если помещается в память и достаточно быстро работает. А в многопрограммной
коммунальной квартире стоит еще и о других подумать. Потому как память хоть и
большая, но не резиновая. И процессор пока что только один, как правило.
был предложен не один способ это сделать, да я и сам предложил с самого начала
свой — как ни плохо .Net я знаю, а все же догадаться несложно было. Мой вопрос в
другом — кто именно этот вариант алгоритма так реализовал, что он вместо
чего-то похожего на n^3 показывает временную зависимость, напоминающую утренние
прыжки моего кота, когда он есть просит ? . Чтобы с увеличением размера
матрицы на 100 время уменьшалось, а при увеличении еще на 200 — увеличивалось в
10 раз —
такого в моей практике еще не было! Не знаю, кто тут виноват, не знаю, кто
эту исполняющую систему писал, но об эффективности здесь говорить не приходится.
Другой пример на эту же тему. Клонирование объектов (deep copy). Рихтер
для этого советует простой способ — сериализовать в memory stream, а потом
десериализовать. Просто ? Да. Изящно ? Да. Только при этом как-то забывают,
что вместо одной операции копирования мы здесь имеем две, и вместо двух
наборов байт (source и destination) имеем три — source, intermediate и
destination.
Правда, Рихтер тут же отмечает, что эта операция может оказаться слишком
дорогой,да и не всегда возможной. Рихтер, безусловно, понимает, когда ее можно
применять, а когда не стоит. Понимают ли это все разработчики под .Net ? Боюсь,
что нет. Так что будут они этот способ использовать, не слишком задумываясь,
скорее всего. Сериализуют двумерную матрицу размером в несколько Мбайт, и все
дела
Кстати, и о самой сериализации. Нет слов — реализовано в .Net красиво. Помечаешь
атрибутом, и все! Только вот не стоит забывать, что бесплатный сэр бывает только
в мышеловках. Конечно, приятно, что за тебя все сделают — reflection, чтение
значений, запись, проход по все ссылкам и опять reflection, чтение значений,
запись. А между тем грамотно написанный код в той же MFC, использующий
сериализацию, сделает в принципе то же самое без того, чтобы изучать
структуру класса(ов) и тратить на это время и память.
В в результате такого отношения — "что нам десяток Мбайт жалеть, что
нам с того, что это здесь на 100 мсек дольше выполняться будет", получается то,
о чем хорошо сказал Cyberax
>Чего-то я начинаю в этой истине сомневаться. Слишком часто все "не
тормозит" (или не жрет памяти) в отдельности, но работает со скоростью
улитки (или жрет гигибайты) в целом.
>Причем наблюдается это, в основном, у современного софта — та же ICQ без
зазрения совести сжирает 20 метров памяти. Какой-нибудь WinAmp еще 20
метров. Вот так и не остается памяти для чего-нибудь полезного....
Хороший, кстати, пример — ICQ. Написана она не на .Net ИМХО (давно
ее не держу, у меня Trillian, ему 7.5 Мбайт хватает . По существу — текстовый редактор плюс модуль связи с winsock. Все остальные возможности его используются
один раз в неделю, если не в месяц. Я ничего против них не имею, но
сидели бы они на диске в виде DLL и раз в неделю загружались! Так нет,
20 Мб вынь да положь! Интересно, под что?
Если бы ICQ был в DOS времена (кстати, был?), то быть бы ему
там TSR размером в 30-40 Кбайт максимум, и писать в нем свои SMS можно было
бы так же, или почти так же, как сейчас, разве что в текстовом
режиме. Да, ладно, бог с ней. с DOS. Сколько места занимали первые
версии ICQ (жаль, не сохранил я тот клиент, с которым начинал лет
8 назад), и сколько сейчас? Памяти много, чего ее жалеть!
Мне тут VladD2 упрек такой кинул — дескать, писать надо , не
слишком думая об эффективности, а потом узкие места можно оптимизировать.
Теоретически — совершенно безупречное рассуждение. А практически — это
верно, если Вы заранее какой-то целью задаетесь — по памяти не более...
или по времени не медленнее ... Если нет — никто и не будет оптимизировать,
потому как совершенно непонятно, что и зачем. Работает каждый модуль раз в
5 дольше , чем можно было бы, памяти кушает раз в 5 больше, чем надо было
бы — что тут оптимизировать? Так и должно быть, все нормально сделали!
В результате получаем некую самодвижущуюся повозку размером с аэроплан,
ставим на нее ракетный двигатель, запускаем — едет! Едет ведь! Со скоростью
60 км/час. Ну вот это и есть настоящий аэроплан, в серию его и пусть
по дорогам ездит. А когда этим разработчикам объясняешь, что аэроплан
должен не ездить, а летать, и не 60, а 900 км/ч давать, а если Вы автомобиль
делали, то он и при двигателе внутреннего сгорания должен эти 60 (а то и 120)
давать, да и размерами должен быть раз в 20 меньше — удивляются, чего, мол,
привязался! Ездят же на нем, чего тебе надо!
А теперь перехожу к главному, что меня беспокоит.
Создается впечатление, что рост быстродействия процессоров несколько
замедлился. Может быть, я не прав, но мне кажется, что мы подошли к некоторому
пределу, и если не последует технологического прорыва, то скорость сильно расти
не будет. Еще раз — может быть, я не прав. Кстати, о памяти пока в этом плане
говорить не приходится.
Но так или иначе — этот предел есть. Очень уж четкие физические
законы здесь действуют, их не обойдешь. Раньше или позже, но бурный рост
мощности ПК заменится если не стагнацией, то более или менее плавным изменением,
на проценты, а не в разы.
И вот тогда этот неэффективный стиль программирования даст себя знать!
Сейчас можно просто рассуждать — чего я буду 20 Мбайт экономить, если
пользователь без проблем 256 может докупить ? А вот когда опять в жестких
лимитах работать придется — окажется, что некоторые программы, которые вполне
могли бы быть написаны, написаны не будут, или же будут написаны лет через 10
после того момента, когда они могли бы появиться! Потому что эффективно
работать большинство не умеет. Привычки у них такие — что нам стоит лишних
десяток Мбайт взять!
Не согласны ? OK, кто из вас взялся бы написать "Turbo Pascal 1.0"
образца 2005 года? Который будет работать в такой маленькой памяти — 512 Мбайт
и на таком медленном процессоре с частотой всего 3 GHz ? Боюсь, что Вы
потребуете для этого 16 Gb памяти и не менее 30 GHz . Вы же прекрасно знаете,
какие ресурсы для чего требуются, поэтому оцените их для этой задачи и получите
16 Gb и 30 GHz, А где их взять? Впрочем, нет, не потребуете. Вы даже задачу
такую не поставите — Вам она и в голову не придет: Боюсь, что мы даже и не
узнаем, что могло бы быть написанным, если бы это эффективно делалось...
Ну и к чему автор призывает, спросите Вы ? К поголовному возврату на
ассемблер
и к 64 Кбайтам ? К отказу от того пути, по которому сейчас пошло развитие ?
Я не настолько наивен, чтобы к этому призывать. Просто одно скажу :
Пишите свои программы эффективно, господа! По крайней мере настолько, насколько
это возможно!
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>это возможно!
Архивредный совет дал нам уважаемый тов.Павел Дворкин!
Несвоевременный!
Какой же несвоевременный совет!
Наоборот, пусть неэффективность плодится и размножается, путь цветет и пахнет. Пусть сотни тысячи индусов копипастят миллионы строчек на managed языках. Пусть фреймворки становятся все толще и прожорливее. Путь рядовой пользователь меняет свой ПК не каждые два года, а каждые полгода. А корпоративные заказчики удваивают мощности своих серверов и класстеров после каждого выпущенного нами сервис-пака. Пусть XML процветает в телекоммуникационных протоколах -- долой всякие ASN1 и прочие двоичные упаковки, экономящие каждый бит. Давайте загадим все интернет каналы под завязку. Пусть это происходит все быстре и быстрее.
Пусть наши заказчики побыстрее увидят, что не выгодно покупать неэффективный (большой, неповоротливый) софт. Так же, как неэффективно ездить по городу на машине, сжигающей 30 литров на 100 киллометров. Так же, как неэффективно использовать 100W лампочку накаливания там, где достаточно использовать 20W галогеновую. Сделаем же так, чтобы рост вычислительной мощности ЭВМ не успевал за прожорливостью нового ПО. Пусть часть работы программиста окажется дешевле часа работы написанной им программы. Раза эдак в три, или в четыре.
Вот тогда наступит наше время.
А пока, не своевременный совет вы даете, уважаемый тов.Павел Дворкин. Эдак вы наши планы раньше времени раскрываете. Демаскируете вы нас, однако.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Минусов мне за эти тезисы поставят, это уж точно.
Что-то не видать.
Щас будет филосовское эссэ... Блииннн...
[...skipped...]
PD>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>это возможно!
Этот вопрос не такой очевидный как кажется. Начать с того, что такое "программа для компьютера"? Какой-нибудь хитрый алгоритм кластеризации в многомерном пространстве — это программа. ICQ — это тоже программа. Но между ними существует фундаментальное различие, которое довольно трудно сформулировать четко и однозначно. Но безусловно то, что это это совершенно разные категории программ. Для пояснения задействуем очень сильное колдунство — О-нотацию. ICQ занимает, скажем 30 мег. Но это все равно O(1) памяти! И до тех пор, пока эта программа работает на 99.99% ширпотребовских компьютеров, нам глубоко пофигу, сколько конкретно пямяти она занимает — это все равно O(1), просто в силу того, что нет такого параметра, от которого бы измерялось это "О". Количество записей в контакт-листе? — нет, это копейки, которые можно вообще не считать (впрочем, это тоже не так-то просто, но об этом — делее).
Другое дело — некий алгоритм кластеризации (это я говорю чисто абстрактно, алгоритм может называться как угодно, скажем, "структурной оптимизации параметрического синтеза"). Он может требовать O(N^2) памяти. Например, для 10 точек — 100 байт памяти, для тысячи точек — уже 10 мег, а для миллиона точек не хватит и всей памяти всех компьютеров на земле.
К чему эти все абстрактные рассуждения? А вот к чему.
Всем людям хочется легких и больших денег. А большие деньги можно сделать только на чем-то очень массовом. А массовое это что? — программа ICQ, например. Или MS Office, whatever. И все эти программы (ну не все, но 99%) относятся к классу сложности O(1) по памяти. Теоретически, это мое утверждение конечно же ложно, но практически — это так. Это раньше было не так, например, когда текстовый редактор требовал O(N) оперативной памяти, а ее всего было 32K, то это был плохой редактор. Файл размером в 100K в нем было принципиально невозможно отредактировать. Требовался редактор класса O(1) оперативной памяти, который динамически работал с дисковой памятью. Как сейчас помню — KED, он же K52, адаптированный под систему команд терминала VT52, который подключался по RS232 на скорости 9600. То есть, реальный канал был менее килобайта в секунду — и это между компьютером и монитором!
После преодоления порога в 640K произошла фундаментальная метаморфоза: тот же текстовый редактор из класса O(N) превратился в класс O(1)! Это опять же, спорное утверждение, но на практике это так. Допустим, у нас есть редактор класса O(N), требующий 1 байт памяти на символ. В 32K памяти можно отредактировать 32K символов. В 640K — 640K символов. А сколько можно отредактировать в одном гигабайте памяти? А самое главное — кому это надо? Лично я не видел ни одного человека, которому бы понадобилось редактировать гиговый текстовый файл. Есть чисто человеческое ограничение — больше мега текста в 99.99% случаев редактировать не требуется. А что такое один мег при объеме памяти в гиг? Именно по причине этого человеческого фактора и появилась принципиальная возможность не заморачиваться такими вещами, как "ручной" динамический своп. Дальше больше — когда сам текстовый редактор с пустым окном занимает 30 мег, а при загрузке 100K текста — 31 мег, мы можем смело считать его редактором класса O(1) — нам никогда не понадобится редактировать такой текстовый файл, который бы существенно увеличил объем занимаемой памяти. А редакторы, ранее бывшие в классе O(1) стали просто не нужны, поскольку работают медленнее. Конечно же я утрирую, но лишь для пояснения идеи — стало можно писать сколько угодно кода, который гарантированно влезает в память. И при условии эффективного хранения данных основная масса программ не требует какой-либо экономии.
Но не тут-то было — сон разума рождает чудовищ. Эта "свобода" породила монстра — неэффективные структуры данных. Взять, например, тот же IE или Firefox. При открытиии ветки на РСДН в 1000 сообщений они отъедают около 10 мег памяти. Десять килобайт на заголовок сообщения! Да сами сообщения в разы меньше! И программы снова превратились в класс O(N). Теоретически. На практике, в 99% случаев можно считать, что они остаются O(1), просто потому, что в большинстве случаев нам не требуется просматривать 1000 сообщений (а если и требуется, то это — исключение). И вот здесь-то и кроется главная причина неэффективности — для получения прибыли достаточно обеспечить работоспособность в 99% случаев, а те, которые требуют большего — они перебьются. Они погоды не делают.
С точки зрения биснеса и легких денег, производители массового софта безусловно правы. Надо стремиться не к какой-то там гипотетической эффективности, а чтобы получить денег — вот здесь и сейчас. Но здесь кроется и главная засада: этот путь тупиковый — такой же, как и любая финансовая пирамида. Рано или поздно рухнет. Кто-то безусловно, на этом мощно заработал и продолжает зарабатывать и получать удовольствия от жизни. Вопрос — сколько это может продолжаться. Может быть долго. Но если не будет нового прорыва в железячной технологи, то коллапс неизбежен. Система является квази-устойчивой: стоит чуть толкнуть — и понеслать п... по кочкам.
И вот здесь мы подходим к главному вопросу — а в чем заключается это "удовольствие от жизни"? Вся индустрия mainstream-софта построена по принципу "американской мечты" — вот мы сейчас зафигачим, продадим, нарубим зеленой капусты, а потом будем всю жизнь "курить бамбук". Безусловно, кому-то это удается, точно так же, как есть шанс получить большие деньги в МЛМ-лохотроне. Другое отношение — это просто "поддерживать жизнедеятельность", то есть, работать на дядю за небольшую, но гарантированную зарплату (ничего не имею против этого — сам такой). Но лично мне и то и другое просто скучно. Мне гораздо интереснее думать — вот это для меня и есть по большому счету удовольствие. Конечно же, я тоже люблю деньги и тоже люблю кататься на доске по снегу с гор и тоже учавствую в этом лохотроне. И мой профессиональный рейтинг повышается, поскольку я стремлюсь к этому повышению. Но я все-таки опасаюсь, что это вся эта индустрия может рухнуть — такое уже было — помните дот-комы?
И именно поэтому я стремлюсь к написанию только эффективного кода. Во-первых, из чисто прагматических соображений. Я убежден (возможно ошибочно) в том, что мои инженерные навыки будут востребованы при любых катаклизмах в индустрии. Во-вторых, мне это просто по жизни нравится — заниматься нетривиальными задачами. Задачи класса O(1) мне неинтересны, хотя, надо признать именно они пока что и обеспечивают в основном мою жизнедеятельность (такова, брат, диалектика). Но я стремлюсь к некому кайфу в жизни — делать только эффективные вещи, интересные мне самому. И в-третьих, моя практика показывает, что это вполне возможно — оставаться в рамках того, что интересно мне и только мне (эффективный код и нетривиальные задачи) и при этом быть востребованным (я этого пока не достиг, но "есть тенденция").
Таким образом, вопрос о написании эффективного/неэффективного кода заключается в рисках и личном выборе этих рмсков. Мой риск — остаться вымершим динозавром. Риск индусов — остаться у разбитого корыта в случае падения рынка индустрии (не надо говорить, что это невозможно — это ОЧЕНЬ возможно). Все-таки, по совокупности факторов, я выбираю путь "динозавра". Индусы ничего не умеют кроме как дубасить мегатонны кривого кода. Я тоже это умею, хотя и не знаю все эти Java-дот-неты так как они знают. Но при этом я умею кое-чего еще, а именно — работать над задачами, сложнее класса O(1).
Не уверен, что моя позиция хороша. По крайней мере, я знаю, что эта ниша невелика и мне вряд ли удастся заработать большие деньги. Большие деньги в индустрии делаются на попсовом, кривом и глючном софте, пожирающем мегабайты. Period! Это никакой не сарказм, это просто факт — так устроен этот мир. Но если захотеть и не лениться, то это вполне реально — делать только эффективные и интересные вещи и при этом "выпивать-закусывать". Это не самый простой путь, но (цитируя Кастанеду), мне представляется, что это — путь с сердцем. А путь "чтоб просто работало" — это путь без сердца. Вот и вся разница. Большинство людей выбирает путь полегче — и они правы! — но это и есть причина того, что "the grass was greener, the taste was sweeter".
И нечего плакаться по поводу того, что "программы раздулись и тысячекратно замедлились". Лично для меня это является совершенно ортогональным фактором к моим интересам.
Надо так (цитата из Х.Забей, "Победил"):
Сражался как п...ц всему
Что было сил,
И выиграл войну.
И победил...
VladD2,
> GZ> Так что если говорить о промышленных языках, то я бы сказал что они есть компромисс — помочь первым, и не мешать вторым. > > Любое достойное дело и или вещь является компромисом. Бескомромисной может быть только вера и преданность.
Sorry, не могу удержаться
Думаю, когда-нибудь ты поймешь, что это очень верный, бескомпромиссный выбор архитекторов дотнета. Выбор архитектурно-чистого решения. Решения которое позволит писать код без компромисов.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Собрался наконец написать. Минусов мне за эти тезисы поставят, это уж точно.
Это вряд ли. Наоборот, правду-матку режешь.
Тут флейм уже заполыхал вовсю на тему проведения границы между тем, когда оптимизировать вредно, и тем, когда это необходимо.
Кратко выскажу несколько мыслей на заданную тему:
Не стоит бояться того, что программисты определенного склада "вымрут". Программистов порождает среда. Когда среда приветствовала нердов — программерами были нерды. Сейчас есть и нерды, которые живут на работе, иногда высовываются в сеть, а живых людей видят только на коференции. Есть и "индусы" — малоквалифицированные люди, которые покрывают потребность в "давай-давай", "нам некогда учиться — надо сдать систему вчера", "если у тебя есть рабочий кусок кода — скопируй его целиком" и так далее. Есть также промежуточное звено — люди, не испытывающие коммуникативных проблем, у которых есть некомпьютерные хобби, но при этом они любят свою работу и стараются делать ее хорошо.
И все это — исключительно потому, что есть потребность в каждой из этих категорий. Напоремся на потолок производительности — те же индусы научатся писать эффективные программы. Ну, не все, а кроме 99% не сумевших и вымерших
Собственно, о самой эффективности. С одной стороны, я полностью согласен с теми, кто придает максимум значения экономии времени программиста. Ребята, время, когда можно было годами полировать текстовый редактор в одиночку, кануло в лету. Сейчас у нас нет времени на эту ерунду. Нам надо удовлетворять потребности бизнеса очень быстро. В первую очередь это означает переход к групповой разработке. Да, до сих пор очень редко в природе встречаются команды численностью более 10 человек. Я подозреваю — из-за технических и организационных проблем. Любой наш заказчик будет счастлив сократить время разработки вдвое. Кроме этого, большое значение имеет стоимость поддержки.
Резюме: понятность программы сейчас значительно важнее ее эффективности (в большинстве случаев!). Соответственно, рулят платформы, которые позволяют писать более понятные программы. Рулят платформы, которые предоставляют исчерпывающую информацию об ошибках, а не Сore Dump. Рулят платформы, которые выполняют рутину за разработчика. Чтобы он мог сосредоточиться на написании действительно существенной части. Потому что ему надо будет писать (а его коллегам читать) меньше кода.
Тем не менее, я тоже испытываю дискомфорт, глядя на неэффективности на ровном месте.
В итоге, я свожу свою мысль к следующему замечанию:
— нельзя ставить эффективность во главу угла. Она не является приоритетом
— Это не значит, что стоит применять заведомо неэффективные решения.
Этого простого правила, я считаю, должно быть достаточно. Остается только тонкость с этим "заведомо". (Это слово, кстати, встречается в тексте статьи 273 УК РФ). Тут каждый решает для себя. Главный критерий — насколько дорого обойдется применение альтернативного решения. Если чувствуешь, что объем работ вырастает больше, чем на 20%-50%, то лучше забей. Если стоимость примерно одинакова — применяй лучшее.
Отдельный разговор надо завести об архитектуре. Premature optimization касается только микро-уровня. Если вдруг в саму архитектуру не было заложено возможности по повышению эффективности, то выполнение mature optimization может оказаться postmature, т.е. слишком поздним. И это сведет полученную экономию средств к нулю.
Ну, и последнее замечание: Очень важно правильно применять оптимизации. В предыдущем пункте я упоминал про неиспользование откровенно неэффективного кода. В большинстве случаев это будут мелкие глупости, вроде вызова new в цикле или ресайза динамического массива на 1. Так вот, на каждой платформе эти хитрости — свои. И ни в коем случае нельзя переносить привычные методы в другую среду. В дотнете new может означать всего лишь очистку памяти. Округление размера выделяемых объектов до "круглых" типа 32, 64 в дотнете контрэффективно — аллокатор сам разберется с выравниванием, а увеличение размера ускоряет забивание хипа и учащает сборку мусора.
Поэтому для выполнения пункта 2 просто необходимо тщательно изучать среду, в которой работаешь. Чтобы, например, нутром чуять, что
...(string a, string b, string c)
{
return"Hello" + a + b + c;
}
— эффективно, а за
...(IEnumerable<string> strings)
{
string s = string.Empty;
foreach(string a in strings) s=s+a;
return s;
}
надо бить линейкой.
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Дарней, Вы писали:
Д>Ну и пусть делают. Я лучше буду иметь дело с неэффективной, но работающей реализацией. Чем с дьявольски эффективной, но ни хрена не работающей
Шас я процитирую (о ужас!) Баяна Ширянова:
Но ведь какая штука, спроси любого ублюдка на улице, что бы он
предпочел: жить долго, но скучно, или коротко, но радостно? И он выберет
последнее. Ну да, не все. Но большинство!
Но, б.., почему этот уличный опрашиваемый не согласится на такой
вариант: долго и радостно? А потому, что он думает, что так не бывает.
Столько лет все рвались к счастливой жизни, что абсолютно в ней
разуверились!
Это я к тому, по достижении "определенной стадии просветления" (это такой само-сарказм) оказывается, что писать эффективный код — это не только приятно и интересно, но он еще и оказывается гораздо надежнее! И стоимость некой абстрактной единицы функциональности оказывается ниже. И что характерно, индустрия, "в которой не место энтузиастам" проявляет тенденцию к спросу на таких "динозавров". Да потому что уже всех достал этот подход — "давайте сделаем это по-быстрому, а потом будем оптимизировать". И это "потом" никогда не наступает — получается как в занудном кошмарном сне — совсем чуть-чуть надо, чтобы вырваться из порочного круга, а не получается — что-то все время мешает.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>С такими ошибками в C++ шаблоны могут помочь бороться.
Заметка из жизни. Если у программиста проблемы с ДНК, то C# многое прощает, а вот шаблоны в С++ многое усугубляют.
Здравствуйте, gear nuke, Вы писали:
GN>Вот, кстати, хороший пример Вы привели. А если человек не понимает, что и почему лучше, он запросто может реализовать то, что первое придёт в голову (пузырёк) .
Да, но есть случаи, когда этот "пузырек" побьет std::sort в разы или даже десятки раз (на почти отсортированных массивах). В моей практике такой случай был, причем очень хитрый. В 99% случаев данные были отсортированы. В 0.9 процентов случаев — почти отсортированы. В 0.1% случаев — практически в беспорядке. Решение таково: пишем bubble sort (да, именно ее). Данная сортировка, являясь "наитупейшей" обладает важным свойством — мы можем контролировать, насколько нам удалось продвинуться и сколько мы сделали перестановок. В 99% случаев она срабатывала без единой перестановки. Но как только количество перестановок превышало некий предел (подобранный эмпирически), мы все бросали и отдавали на съедение quick sort. Это эмпирическое знание позволило ускорить некий процесс обработки данных более чем вдвое, по сравнению с просто вызовом std::sort().
К чему я все это? — да ни к чему, просто случай из практики. Ну и к тому, что "ученье — свет", "инженер — это звучит гордо" (в качестве само-сарказма). А так же к тому, что пути оптимизации неисповедимы.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Жаль только жить в это времы прекрасное уж не придется ни мне, ни тебе...
...поскольку крупные поставщики ПО в сговоре с железячниками — что б было как в анекдоте: кончилась водка, осталась закуска, сбегали за водкой, кончилась закуска, купили закуски...
Эффективное ПО также ненужно корпорациям как:
— вечная лампочка (почти вечная придумана давно)
— туфли на неснашиваемой подошве (казалось бы — чего проще пустить туда резину как в авто-покрышках)
— экономичные автомобили
— удобные и дешевые сотовые телефоны
Необходимость в написании ну о-о-о-очень эффективных программ отпала. И слава богу. Туда и дорога.
Потому что единственными, кто был в этом заинтересован, были сами компьютерные энтузиасты (вроде вас, автор?), которые предпочитали ... э-э-э-э заниматься с компьютером любовью непременно стоя и непременно в гамаке.
А почти полная утеря общественностью навыков эффективного создания каменных топоров вас не волнует? А врдруг железо закончится, что делать будем?
Индустрия променяла эффективность кода на эффективность труда. И на его облегчение. Что тут плохого?
Описанная картина неизбежного апокалипсиса тоже сильно преувеличена.
Программы редко пишутся в расчете на то, что железо подрастет. Крупные игры, ОС и прочие перспективные разработки в основном. Мы же, простые прикладные смертные, имеем дело с тем, что есть. И выбор между экономией тактов и экономией человеко-часов стараемся делать однозначный.
Поэтому то, что есть.. java/.net, массивные framework-и и Windows XP никуда не денутся, даже если прогресс резко остановится.Эти вещи пришли, чтобы остаться. А если прогресс не замедлится, то мы постараемся занять и те ресурсы, что будут нам предоставлены. Зачем?
Понимаете, автор... гигабайт свободной оперативной памяти при запущенной IDE греет душу не всем. Мне, например, нет. А вот возврата к временам, когда редактор кода в IDE не умеет подсвечивать синтаксис и указывать на допущенные мной ошибки в background-е я не хочу.
И не надо мне говорить, что это не связанные вещи. Что компиляция в background-е была бы все равно, причем быстрее и надежнее. Ее бы не было именно потому, что ее пришлось бы писать на каком-нибудь asm-е с использованием столь эффектно описанного вами механизма самопожирания программы. Руки бы не дошли — надо было бы drag&drop прикручивать и баги в компиляторе исправлять. А может эту фичу вообще не стали бы делать — памяти ого-го сколько отжирает, целых 121 232 байта! В уме нужно компилировать, слабак!
За все нужно платить. Текущая плата лично мне представляется в высшей степени щадящей.
Кроме того, вы путаете причину и следствие. Проблема не в том, что основная масса "программистов" не умеет оптимизировать свой код. Проблема в том, что они вообще очень мало, что умеют, а обучаться не могут или не хотят.
Раньше было не так? Да, но раньше это была элитарная профессия. А теперь потребность в кодерах возрасла многократно (несмотря на то, что эффективность труда тоже) и уровень, разумеется, упал. И отсутствие оптимизации — это меньшее из всех зол.
GlebZ,
> ПК>С такими ошибками в C++ шаблоны могут помочь бороться.
> Заметка из жизни. Если у программиста проблемы с ДНК, то C# многое прощает, а вот шаблоны в С++ многое усугубляют.
Если у программиста проблемы с ДНК, то лечится это не инструментальными средствами. Инструменты, напротив, должны давать возможности тем программистам, у которых с ДНК все в порядке.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, mrozov, Вы писали:
S>>Такие вот интсрументы эти Ваши вилки
M>Простите, у вас есть дети? M>Я имею в виду, знаете ли вы, какие меры предосторожности нужно предпринимать, если в доме есть ребенок, умеющий ходить, но еще не имеющий развитого инстинкта самосохранения?
Отлично, тема детей, это очень даже хорошо
Счас скоррелируем с вилками
Для детей, промышленностью, выпускаються специальные столовые приборы, ткакже как и средства гигиены.
Соответсвенно, взрослым, или как Вы изволили вырвзиться
умелецы по части поедания фруктов не теряя достоинства
Здравствуйте, eao197, Вы писали:
PD>>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>>это возможно!
E>Имхо, пока за скорость разработки платят больше, чем за скорость работы заказанной программы, этот призыв останется "гласом вопиющего в пустыне".
Платят не за скорость разработки, и не за скорость программы которая получается в результате разработки. Платят за решение своих проблем. Программа должна решать задачи заказчика. Делать это она должна с примлемой производительностью на имеющемся у него железе. И решать эти задачи программа должна не через 10 лет, а сейчас. Причем программа еще должна стоить приемлемые для заказчика деньги.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
GlebZ,
> Кроме того, тут стоит говорить не только о Framework, но вообще о языках высокого уровня. Не секрет, что язык высокого уровня генерит избыточный код и избыточно использует память. И чем выше язык, тем труднее поддается оптимизация кода компилятором.
Это не совсем так. Например, те же функциональные языки часто "уделывают" ряд других, менее высокоуровневых "конкурентов". В общем, корреляция не вполне установлена.
> В принципе, если взять тот-же STL, то говорить о том, что он по скорости 1 в 1 с кодом написанным вручную на С не приходится.
Да, часто быстрее.
> А string вообще кошмар, но зато жутко удобный.
Это к уровню языка отношения не имеет.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
>> Любое достойное дело и или вещь является компромисом. Бескомромисной может быть только вера и преданность.
ПК>Sorry, не могу удержаться
ПК>
ПК>Думаю, когда-нибудь ты поймешь, что это очень верный, бескомпромиссный выбор архитекторов дотнета. Выбор архитектурно-чистого решения. Решения которое позволит писать код без компромисов.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD> И вот тогда этот неэффективный стиль программирования даст себя знать! PD>Сейчас можно просто рассуждать — чего я буду 20 Мбайт экономить, если PD>пользователь без проблем 256 может докупить ? А вот когда опять в жестких PD>лимитах работать придется — окажется, что некоторые программы, которые вполне PD>могли бы быть написаны, написаны не будут, или же будут написаны лет через 10 PD>после того момента, когда они могли бы появиться! Потому что эффективно PD>работать большинство не умеет. Привычки у них такие — что нам стоит лишних PD>десяток Мбайт взять!
Научить обычного, не озабоченного "оптимизацией-везде-где-можно" программиста оптимизировать программы куда проще, чем научить "байтовыжимателя" писать нормальный и понятный код. Потому что второй всегда будет искать, как в .NET обнулить поля структуры с помощью ZeroMemory (да-да, это намек ) — вместо того, чтобы проектировать архитектуру. Да еще и считать окружающих идиотами, потому что они не понимают, как же это важно — обязательно залезть на нижний уровень по самый локоть.
It is far, far easier to make a correct program fast than it is to make a fast program correct. (c) C++ Coding Standards: 101 Rules, Guidelines, and Best Practices
Ну и от себя (хотя тоже не мое):
Заказчик: Нам нужна программа, которая будет стоить не дорого, работать — быстро, и сделать ее надо срочно.
Программисты: Из трех перечисленных условий выберите любые два.
If a shark stops swimming, it will die. Don't stop swimming, Mr. Mulder.
Every epic equalizer is iso (c)
Centaur wrote:
> Однако, в наше время таки оптимизировать всё до последнего байта есть > непозволительная роскошь. Моё время как разработчика несравненно > дороже времени процессора и оперативной памяти.
Дайте я придумаю цитату: "Если разработчик экономит свое время, то он
тратит время своих пользователей".
> Пишите свои программы понятно, господа! Если использование показывает, > что память — узкое место, найдите 10% кода, которые используют 90% памяти.
Миф. Современные программы тормозят одинаково по всему коду.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Есть такой класс программистов — программисты на Visual Basic. VB как-то в России не слишком популярен ИМХО и признаваться, что на нем пишешь, даже как-то стыдно считалось . А вот в мире он весьма популярен, где-то мне встретилось утверждение, что в мире около 1 млн. программистов на VB. За то. что мне память здесь не изменяет — не поручусь, так что критиковать это утверждение не надо. И потом, неизвестно кого они туда включили — может, школьников средних школ тоже
PD>Так вот, эти самые программисты на VB свою работу делали, а вот эффективности от них никто и не ждал. Потому что программы для массового использования они не делали, а делали для данного конкретного случая, порой для себя, или для заказчика, которому она нужна, а торговать он ей вовсе не собирается. Кстати, если во времена своих химических расчетов имел бы PC с VB — вполне возможно, на нем бы и начал свою карьеру. Просто, удобно, легко...
PD>Что касается эффективности — кто ее от Бейсика когда ждал ? К нему традиционное отношение как к чему-то неэффективному — интерпретатор же! И пусть VB никакой не интерпретатор — от однажды завоеванной репутации так легко не отделаешься
PD>Так вот, у меня впечатление такое, что этот стиль VB попросту начинает проникать в те области, куда программистов VB раньше и на пушечный выстрел не подпускали, да они и сами не стремились, так как знали, что им там делать нечего — не влезут они с VB в имеющиеся ресурсы, не добьются нужной производительности. А ресурсы увеличились — и они пошли!
Есть у меня на работе одна система. Клиентская часть написана на VC6. Около полумега cpp-шек. Многопоточная, большой объем взаимодействия с системой, работа с Oracle и прочие мелочи. Работать она должна на машинах с 32 мегами памяти (потому что есть у нас и такие). Ничего, работает. На тысяче машин где-то. Параллельно.
Есть для нее панель управления. Через которую ею администраторы управляют. Ее писал на VB6. Почему? Потому что надо быстро было писать, и чтобы работало. Больше сотни окошек в ней, а написана была за 4 месяца. Кстати, с собственным, заточенным под нее гридом (работает, чертяка, идеально). Памяти жрет под полсотни мег. Ну и что? У админов ее все равно 512. Не то, что у пользователей.
Так я к чему? Не надо лепить ярлыки на людей. Я пишу на том, на чем данную задачу написать правильнее, а не на том, что мне нравится. Почему — да не нужна мне лишняя головная боль потом с сопровождением.
Кстати, об эффективности. На VB, бывает, тоже приходится данные локально обсчитывать. И где пооптимизировать — находится...
Простите, у вас есть дети?
Я имею в виду, знаете ли вы, какие меры предосторожности нужно предпринимать, если в доме есть ребенок, умеющий ходить, но еще не имеющий развитого инстинкта самосохранения?
Но главное не это. Главное то, что я, как и подавляющее большинство населения, фруктовыми вилками не пользуюсь. Зато пользуюсь чайными ложками. И человека, который заявляет, что "Чайные ложки не нужны, вот фруктовые вилки — это круто!", я всерьез воспринимать затрудняюсь. Так как он, вполне вероятно, большуй умелец по части поедания фруктов не теряя достоинства, но вот с кругозором и трезвой самооценкой у него явно некоторые проблемы
Здравствуйте, McSeem2, Вы писали:
E>>А поиск в Janus я привел как пример распространенного подхода: сделать работоспособный вариант без учета его эффективности. А потом, когда это станет проблемой, оптимизировать.
E>>Тут уже кто-то сказал, что это "потом" никогда не наступает.
MS>Это был я
MS>Но зададим себе вопрос — "а оно надо"? Может быть и не нужен поиск в Janus? Или нужен?
Мне нужен
Иногда возникает какой-нибудь вопрос, который уже затрагивался где-то или просто хочется привести ссылки на какие-то факты. Вот, как здесь: Re: Открыли зачем?
P.S.
> Какое отношение к string имеет уровень языка, и string к уровню языка? В лучшем случае тут можно говорить об уровне абстракции. Но и в этом случае вряд ли можно говорить об универсальной зависимости производительности от уровня абстракции. Иными словами, в данном случае производится попытка сделать общий вывод (зависимость производительности от уровня языка) из частных моментов (производительность char[] vs. std::string), не вполне относящихся к ходу рассуждений (уровень языка здесь, имхо, ни при чем).
Кстати, для C++ Степановым в свое время даже был написан набор их 13 тестов, меряющих так называемую abstraction penalty. Для современных компиляторов (Intel C++, Visual C++) abstraction penalty в соответствии с этим тестом, если и проявляется, то "плавает" в пределах единиц процентов.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, eao197, Вы писали:
E>Возьмем Janus. Когда я пишу это сообщение он у меня занимает в пямяти 53Mb. Сам инсталлятор у него маленький, но к нему же еще и .Net нужен. А к следующим версиям еще и .Net 2.0 потребуется. А уж поиск по базе сообщений по скорости с Opera вообще не сравнится. Да и объем сохраняемых сообщений на диске не маленький. Так что для меня Janus удобная программа, но вот эффективной я ее назвать не могу. А если для повышения ее эффективности для хранения сообщений вообще что-то посерьезнее Jet-та потребуется (какой-нибудь FireBird или MSSQL), то вообще...
Улыбнуло капитально.
Каждый программер на заре своей карьеры торжественно клянется — "Шоб я писал тормозные, глюкавые программы ... да шоб мне гореть в аду, если такое произойдет". Те, кто все таки становится профессионалом, говорят на эту тему уже гораздо осторожнее. Ибо познакомились с реалиями своей профессии.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>это возможно!
Не согласится не возможно.
Сперва, хочу все-таки попросить всех участников форума быть разумными "насколько это возможно!" (с) Pavel Dvorkin и не скатываться на обсуждение технологий и ЯП — жаль, что это сделал Павел.
Да, я, безусловно, ЗА эффективный код. Сам иногда удивляюсь вопиющему пофигизму к эффективности. Только ИМХО эффективность нынче меряется далеко не объемом используемой оперативки и быстродействием. Эффективность трансформирповалась нечто другое. Посмотрим на нее в немного другой плоскости. Буду говорить об эффективноти 2х типов: эфективность на уровне кода и на уровне технологий.
Эффективность на уровне кода.
Простейший пример неэффективности приведу из проекта, в который с недавнего времени пришел. Один коллега пишет:
for (int i = 0; i < reporter.GetDistributorsCount()*reporter.GetReportTypesCount(); i++)
{
// работа с БД
}
Я сказал, что это не очень красиво и попросил переписать сие безобразие на следующий код:
for (int i = 0, count = reporter.GetDistributorsCount()*reporter.GetReportTypesCount(); i < count; i++)
{
// работа с БД
}
На что мне открыто заявили: "reporter.GetDistributorsCount()*reporter.GetReportTypesCount() — это ничто по сравнению тем, что находится в теле цикла! работа с БД уничтожит эту оптимизацию". Уж не знаю и правда ли он так думает или для него слишком уж обидно, когда вчерашний студент учит код писать профессионала со стажем. Ну не прав он. На все 100 не прав. Когда в метод GetDistributorsCount(), однажды добавят работу с БД, а то и с веб-сервисами (на самом деле в этот метод вряд ли, а в другой?), тогда начнет плоды пожимать. А что, тяжело сразу написать эффективно?
Дело тут не в расбрасывании ценными килобайтами памяти, а в неэффективности с точки зрения поддержи кода и системы в целом.
Буду ли я оптимизировать работу с матрицами? — It depends... По большей части от поставленной задачи. Стараться сделать все как можно оптимальнее, определенно буду. Но скорее всего у начальства не вызовет восторга, на то, чтоб даже 5-6 часов, я сделал код экономящий пару МБ.
Действительно, мы сейчас живем в век дешевой техники и дорогой рабочей силы. Но экономя на поддержке и разработке многие, прежде всего заказчики и начальники, действительно портят программистов. Что однако не умоляет множество глупых и бездарных программ.
По поводу ICQ-клиента — Miranda рулит
Эффективность на уровне технологий.
Вот с архитектором в проекте очень даже повезло. Сейчас используется 5 ЯП с соответсвующими им технологиями. Я бы еще пол года назад сказал бы — да зачем мне какой-то там Питон, .NET форева. (Надеюсь больше меня эти мысли посещать не будут.) Все от начала до конца можно было сделать на .NET. Однако, прилили и C++, и Питон, и Ява Скритп, и Перл. Чего добились — думали: путаницы и неразберихи — оказалось: простоты и эффективноти!
Что я хочу этим сказать — ну сколько можно доказывать друг другу, что вот так вот в # не сделаешь, а вот так в ++ (хотя сам люблю друзьям ++никам, за кружечкой пива обяснить, что ++ — это так — игрушки ). Пора уже давно выяснить сильные стороны каждой из технологий и использовать их. А будь мне действительно так важны те 2 МБ при работе с матрицами — сяду за плюсы и глазом не моргну. Чего и вам, Павел, желаю.
Здравствуйте, alexeiz, Вы писали:
A>Абсолютно верно. Мы уже подошли к пределу. У меня 3GHz процессор уже два года. И никакого двухкратного скачка частоты за 18 месяцев не предвидется.
Да, закон Мура уже не работает несколько лет!
И ещё "нюанс", про который забывают говорить — архитектура современных компьютеров далека от фон-неймановской. Вы видите 3GHz + 2Gb памяти, а на самом деле... 3GHz + 512Kb (Вам ещё повезло, у Celeron кеш меньше в 2\4 раза). Остальная память работает со скоростью на порядок меньше.
Отсюда и отсутствие различия в скорости работы кода откомпилированного MSVC с опцией /clr и без неё. Сравнивается 2 неоптимальных варианта.
A>http://www.gotw.ca/publications/concurrency-ddj.htm
A>Тем не менее плотность транзисторов можно наращивать и дальше.
Я бы сказал — до сих пор удавалось находить решения технологических проблем.
A>Поэтому процессорная индустрия переходит из области гонки за частоту в область много ядерных процессоров (multicore). Уже существуют dual-core Intel Pentium D & AMD Athlon64 X2. В скором будущем у нас будут гораздо больше core, порядка десяти.
2 ядра — та ещё "конфетка". Ни о каком увиличении скорости в 2 раза речи быть не может. Общая шина памяти, необходимость в когеррентности данных в кеше — это только низкоуровневые железнае проблемы. Когда будет 8 ядер все эти заморочки только усугубятся. Эффективных способов решения нет, и, боюсь, не будет.
Но давайте попробуем заглянуть в будующее:
— бездисковые терминалы с тонкими каналами; загрузка огромного приложения с сервра будет напоминать о загрузке с магнитофона.
— workstation, являющиеся одновременно и "personal" web server — крутится большое количество сервисов, интерпретаторов, БД и прочего. А ещё хочется mp4 посмотреть, да и не закрывать браузер с десятками открытых страниц.
ИМХО не стоит забывать, что развитие часто идёт по спирали...
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
Здравствуйте, GlebZ, Вы писали:
GZ>А ты дать определение, что такое эффективный софт. И что такое неэффективный софт?
А еще определение "оптимизации" Это мне как-то на защите диссертации довелось побывать. Там человек защищался по инструментальной системе для кросс-ассемблерной разработки. Для того, чтобы очень сильная прикладная работа имела хоть какой-то оттенок научности в диссертацию вставили что-то про "оптимизацию разработке". И вот на защите бедолага диссертант взял да и ляпнул не к месту это слово. До этого дяденьки из совета чесно дремали, т.к. большинство из них слобо понимало, о чем вообще речь. А тут! Да у большинства из них оптимизация чего-то там -- это хлеб родной. Вот и спросили товарища: "Дайте определение оптимальной функции!"... Хорошо еще, что все хорошо закончилось.
Может давай я тебе еще пару примеров приведу к тому, что Павел у себя указал?
Вот берем браузер Opera. В нем еще и RSS-ридер есть, и почтовый клиент. И поиск по почте/сообщениям за доли секунды выполняется. И сам браузер 3.5Mb в дистрибутиве занимает (без Java). И памяти при работе у меня сейчас 44Mb занимает с 14-ю открытыми табами. Кому как, а по мне Opera весьма эффективная программа.
Возьмем Janus. Когда я пишу это сообщение он у меня занимает в пямяти 53Mb. Сам инсталлятор у него маленький, но к нему же еще и .Net нужен. А к следующим версиям еще и .Net 2.0 потребуется. А уж поиск по базе сообщений по скорости с Opera вообще не сравнится. Да и объем сохраняемых сообщений на диске не маленький. Так что для меня Janus удобная программа, но вот эффективной я ее назвать не могу. А если для повышения ее эффективности для хранения сообщений вообще что-то посерьезнее Jet-та потребуется (какой-нибудь FireBird или MSSQL), то вообще...
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Nickolay Ch, Вы писали:
NC>Буду краток: писать код надо так, чтобы из него можно было получить максимальную денежную прибыль. NC>Энтузиастам и "вольным художникам" не место в индустрии.
Именно поэтому на моем винчестере остается все меньше программ, которые делались для получения максимальной денежной выгоды. Так как программы, написаные энтузиастами и вольными художниками все чаще становятся лучше коммерческих собратьев.
Хорошие коммерческие продукты, которые я использую, НЕ живут по правилу "максимальной денежной прибыли", а по правилу "Делать все, чтобы пользователям было удобно — тогда и прибыль будет".
Здравствуйте, Nickolay Ch, Вы писали:
NC>...писать код надо так, чтобы из него можно было получить максимальную денежную прибыль... NC>...Энтузиастам и "вольным художникам" не место в индустрии...
Мда. Энтузиасты и вольные художники формируют эту индустрию.
Ну да к вечеру вернется McSeem2, он тебе подробнее объяснит
C>Пишите свои программы понятно, господа! Если использование показывает, что память — узкое место, найдите 10% кода, которые используют 90% памяти. Если использование показывает, что узкое место — процессорное время, найдите 10% кода, которые работают 90% времени.
Почему все легко так выстреливают — "фигня вопрос, углубить, улучшить.... пара пустяков".
А слишком поздно небудет? Что Вы будете делать если борьба с этими процентами заставит взорвать весь фундамент, пересмотреть всю архитектуру?
Я не верю, что прогу написанную без размышлений о разумном использовании рессурсов так просто сделать эффективной.
Попробовал сейчас в VC7. Да, он действительно генерирует несколько своеобразный код, который быстрее примерно в 2 раза. Впрочм, тихого ужаса все равно нет.
; 19 : {
; 20 :
; 21 : for(int i = 0; i < 100000; i++)
xor eax, eax
$L19464:
; 22 : if(a[i] == 666)
cmp DWORD PTR _a$[esp+eax*4+400012], esi
je SHORT $L19461
cmp DWORD PTR _a$[esp+eax*4+400016], esi
je SHORT $L19461
cmp DWORD PTR _a$[esp+eax*4+400020], esi
je SHORT $L19461
cmp DWORD PTR _a$[esp+eax*4+400024], esi
je SHORT $L19461
cmp DWORD PTR _a$[esp+eax*4+400028], esi
je SHORT $L19461
add eax, 5
cmp eax, 100000 ; 000186a0H
jl SHORT $L19464
$L19461:
Проверил я и вариант с repne scasd. Точно, медленнее.
Так что я должен с тобой согласиться — неплохо они компилятор сделали. Жаль, у меня Intel compiler не установлен, любопытно было бы сравнить.
GlebZ,
> ПК>Если у программиста проблемы с ДНК, то лечится это не инструментальными средствами. Инструменты, напротив, должны давать возможности тем программистам, у которых с ДНК все в порядке.
> Только вопрос в том, что для кого программирование работа, а для кого-то призвание. И первых значительно больше чем вторых.
Теперь осталось определить, в какой степени мне важны интересы первых при выборе инструментальных средств, и на этом можно будет поставить точку в этой дискуссии. Пожалуй, с чем я легко могу согласиться, так это с тем, что в высказывании, процитированном выше, мне следовало подчеркнуть, что речь идет о тех инструментах, которые интересуют меня лично. Об остальных у меня мнения, кроме того, что они мне неинтересны, нет.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Абстракции — абстрациями, а конкретика — конкретикой.
То, что вы не призываете заниматься микрооптимизацией — это замечательно. Хотя в свете существования компиляторов, которые оптимизируют ассемблерный код лучше, чем 99% программистов — это не так уж и удивительно .Однако из ваших постов можно сделать вывод, что вы отказываете в праве на существование (доминирование?) таким системам, как Java или .net, именно на основе их неоптимальности. И в моих (например) глазах такие тезисы абсолютно равнозначны призывам массово использовать asm для построения UI.
Тезис, который до вас на разные лады пытаются донести десятки участвующих в этой дискусии таков:
Излишней является любая оптимизация, которая не направлена на изменение ситуации, при которой система не способна уложиться в определенные в проекте временные рамки на том оборудовании, для работы на котором она предназначена.
Не больше. не меньше. Иными словами — для любого ПО можно (нужно?) определить минимально допустимую конфигурацию (критерии могут быть разными) и необходимые показатели быстродействия (в основном — время отклика). И любая система, укладывающаяся в эти рамки, является достаточно оптимальной, вне зависимости от того, насколько еще можно ускорить ее работу.
И если вышеописанные критерии выбраны правильно, то дальнейшая оптимизация системы не способна принести проекту никаких дополнительных дивидендов. Время же. потраченное на дополнительную оптимизацию, наносит проекту непосредственный вред.
По-моему, это клинический факт. Спорить можно только с тем, насколько вольно постановщик задачи обращается с этими самыми критериями достаточности. Сложившаяся тенеденция быстрого роста и дешевизны ресурсов действительно часто приводят к рождению неповоротливых монстров. Но это именно частность, которая не может отменить общую тенденцию.
P.S. А вообще — я сам очень люблю шлифовать код. Но очень редко могу себе это позволить.
PD> Я не настолько наивен, чтобы к этому призывать. Просто одно скажу :
PD>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>это возможно!
Давайте разберемся с критерием "насколько это возможно", судя по тому что подход используемый в индсутрии выраженный владом: "оптимизируй только там где это необходимо" смею предположить что вы проповедуете подход "чем больше тем лучше"?
А вы представляете сколько будет стоить такая программа?
И где набрать столько высококвалифицированных программистов?
И какое количество ошибок будет содержать такое highly optimized приложение?
В результате может получиться обратная ситуация:
у пользователя есть компутер с 300МHz тактовой частотой, 128Мб памяти, и
ОS windows Effective (tm) которая будет показывать чудеса производительности на данной конфигурации но одна лицензия будет стоить 15000$.
Имхо, индустрия сама отлично себя регулирует: пока труд программистов стоит дороже железяк — будет сохранятся текущая ситуация. Изменится соотношение — изменится и отношение
PS: приложений где нужны эффективные решения и тотальная оптимизация достаточно много.
Но для большинства десктоп приложений оптимизация и эффективность не нужна. Если мне предложат МС офис за 100$ но который при этом будет жрать ресурсов в два раза больше — я предпочту его, докупив нужное количество процессора и памяти
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Этот код НЕ вызывается из обработчика ВЕБ-форм. В этом случае так писать действительно не стоит. Этот код берет проверенные значения из БД, где для их хранения НЕ ОТВЕДЕНО 500 char. По-прежнему будешь утверждать ?
Я тут не поленился и сделал тест...
private static string Concat(string s1, string s2)
{
return s1 + s2;
}
...
for (int i = 0; i < 100000; ++i)
Concat("iddqd", "idkfa");
0.02506806
Итого: C# в 2 раза быстрее чем С++ (при том что в C# при каждом сложении происходит выделение памяти и работа идет с юникодом) и самое главное то что код на C# безопасен.
ЗЫ Замеры производились 100 раз. Самые быстрые и самые медленные результаты отбрасывались, остальные усреднялись.
ЗЗЫ VS 2003
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, VladD2, Вы писали:
GZ>>Влад. Только не надо говорить что все программирование ограничивается бизнес-приложениями. VD>Я где-то такое говорил?
Ты такое недвусмысленно подразумевал.
VD>Одно дело знать, что такое блок памяти, а другое думать только ими.
Неее. Я до сих пор думаю ими. И это мне помогает понять язык. И тебе тоже. А особенно помогает работать с массивами. И смотреть чтобы не было копирования больших данных. И тут абстракция не поможет. Здесь нужно иметь привычку делать так, чтобы потом кардинально не переделывать. Это в большей степени не проблема дизайна, а алгоритмическая проблема. Хотя меру тоже надо знать.
VD>Возможно я излишне резок,
+1. Именно излишне. VD>но меня просто выворачивает на изнанку когдя я представляю себе плоды подобного обучения.
Мы с тобой(судя по возрасту) плоды такого обучения. И я рад что прошел школу 286 процессора и CGA экрана. Очень обучает думать. Так кто там мерял скорость GDI+?
Правильно действовать легко научить. Правильно думать — значительно труднее. И для системы алгоритм+доступные_ресурсы — нужно учиться думать.
Думать абстракциями — также нужно учить. То же очень сложная штука. Но это и не обозначает отмену вышеописанного.
С уважением, Gleb.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Собрался наконец написать. Минусов мне за эти тезисы поставят, это уж точно. Ну PD>что же — к счастью, я уже не в том возрасте, когда падение или рост рейтинга PD>могут серьезно повлиять на самочувствие.
Минус — это знак несогласия с сообщением, а не рейтинга. А в таком большом посте, трудно найти вещь с которой абсолютно несогласен.
PD> И действительно, как было не признать! Пока программа небольшая и в память PD>помещается — ладно, живите и радуйтесь! Ну а как побольше стала ? Тут-то и PD>придется признать свое бессилие. А гуру, им что, всегда что-нибудь придумают. PD>Кто-нибудь из нынешнего поколения слышал про "самоубийство программ" ? Нет, это PD>не стирание EXE-файла во время его работы. Это когда программа во время своей PD>работы использует память, занятую своими командами (которые уже отработали и PD>больше не потребуются) под свои данные.
У меня это называлось overlay.
PD> В общем, если говорить серьезнее, эффективность у нас была всегда на PD>первом плане. Не как-нибудь написать, а наиболее эффективным способом, PD>не любой алгоритм использовать, а лучший для этого случая. На этом мы PD>прочно стояли.
Эффективность бывает разной. Можно написать программу, которая будет выполняться в 100 раз быстрее, но и содержать в 100 раз больше ошибок. И отладить эти ошибки будет практически невозможно. Поэтому эффективность — это не только скорость и потребление ресурсов.
PD> Чудо называлось Turbo Pascal 1.0. Сказать, что он меня поразил — не то PD>слово. И не меня только. Все, кто до этого Ямаху не видел (а их в Омск PD>очень немного попало тогда) и кому я о нем говорил, отвечали мне одинаково- PD>такого не может быть!
Ага, и встроенный бейсик в Ямахе тоже был.
PD> А потом компьютеры, хоть и не меньше и не больше по размерам стали, начали PD>резко увеличивать свою память и быстродействие. Сейчас любят вспоминать PD>пророчество Б.Гейтса — дескать, 256 Кбайт всем хватит.
Вообще-то Билли говорил о 640.
PD> Вот тут первые шаги в сторону пренебрежения оптимальностью уже и начались. PD>Действительно, на машине 600 Кбайт свободно, машина однопрограммная, PD>конкурентов нет, зачем мне пытаться программу в 100 Кбайт уложить ,если можно PD>все 500 спокойно использовать. Впрочем, память памятью, а есть еще и PD>быстродействие. Оно было еще очень маленьким, так что хотя бы в этом PD>плане писать все же приходилось эффективно, выжимать из машины все, что можно. PD>Так что писать старались все же эффективно, хотя десятком, а то и сотней PD>лишних Кбайт уже не мелочились.
Ну да. Только памяти никогда не хватало. И задачи, которые надо было реализовать, становились все больше и функциональнее. И потом все эти перегрузки памяти из extented в expanded. Все ради эффективности программы. Но самое главное, можно было быть уверенным за 400 килобайт нормальной памяти, и что тебе никто в соседнем процессе мешать не будет. Если было больше 400, то у многих клиентов программы отваливались. Для запуска некоторых программ, приходилось здорово подредактировать config.sys и autoexec.bat. Так что абсолютного счастья тогда не было.
PD> Дудки вам, а не 640 Кбайт. В 640 Кбайт сейчас умеют только "Hello, PD>World" укладывать! Пока несколько десятков Мбайт не будет, и не подходите.
Ты Турбо-Vision пользовался? Достаточно эффективная библиотека, с очень большими возможностями. Но из-за того, что возможностей много то занимала много обычной и самой дорогой conversional memory. Поэтому, либо пиши все ручками (это будет эффективно по скорости и памяти), либо используй библиотеку и борись за память. А потом проблемы ушли. Может это и к лучшему?
Я тоже горячился когда оказалось что exe файл для Delphi был больше мега(сейчас не помню, но для тех времен очень много). Но то, что я мог мышью быстро собрать приложение и получить за него деньги перевешивало. Как программисту который уважает свое творчество, это плохо. А вот для человека который пытается на хлеб масло намазать, чрезвычайно хорошо.
PD> Другой пример — сама Windows. Я прекрасно понимаю, что Windows NT 4 и PD>Windows XP — не совсем одно и то же. Но та на 8 Мбайтах работала, а эта от PD>128 нос воротит, подавай ей 256.
NT 4.0 на 8 мегабайтах не работала, а обслуживала саму себя. И то, если сервис паки не ставить. PD>А ядро, вообще говоря, претерпело не такие уж большие изменения.
Так оно места то много не занимает. Оно действительно эффективно. А вот если говорить о сопутсвующих процессах, типа сервисов и т.д., или тех же картинок, то это и есть увеличение. С установкой сервис паков и добавления функциональности, ситуация выравнивается.
Хотя согласен, многое можно было-бы сделать пооптимальнее.
PD>программа занимала 8 Мбайт, если можно взять 64 ? Даже, пожалуй, наоборот- PD>увидят, что твоя программа меньше памяти занимает, чем у конкурента — ну PD>и решат, что та более крутая
Дудки, такого не было. Программа должна либо работать, либо не работать и тормозить. Это и есть показатель эффективности был, есть и будет.
PD> Я не против удобства и простоты. Я за. А вот что такое "достаточной" — PD>извольте объяснить. Если машина однопрограммная — тогда, конечно, достаточно — PD>если помещается в память и достаточно быстро работает. А в многопрограммной PD>коммунальной квартире стоит еще и о других подумать. Потому как память хоть и PD>большая, но не резиновая. И процессор пока что только один, как правило.
Если пользователь будет одновременно работать с моей программой, с 10 вордами, 50 акцессами, и 30 экселами одновременно, то у него моя программа будет тормозить. Скажи мне, это я в этом не виноват? Ты можешь сформулировать когда программу можно считать избыточной?
PD>Или вот другой пример — с умножением матриц
Вроде дошли до того, что здесь кэш процессора играет слишком большую роль.
PD>Правда, Рихтер тут же отмечает, что эта операция может оказаться слишком PD>дорогой,да и не всегда возможной. Рихтер, безусловно, понимает, когда ее можно PD>применять, а когда не стоит. Понимают ли это все разработчики под .Net ? Боюсь, PD>что нет. Так что будут они этот способ использовать, не слишком задумываясь, PD>скорее всего. Сериализуют двумерную матрицу размером в несколько Мбайт, и все PD>дела
Это взгляд со стороны. Разработчики все понимают. Но понимают и другое. Здесь уже несколько раз обсуждалось. Ошибиться в том, что ты неправильно определил место торможения, потратил много времени и сил на работу которая не нужна, значительно хуже. Поэтому лучше сначало сделать, а потом заниматься выявлением узких мест. А также оптимизацией памяти, если ее оказалось недостаточно.
PD>Хороший, кстати, пример — ICQ. Написана она не на .Net ИМХО (давно
Жадные вы. Че вам памяти жалко?
Во первых, ICQ — это глюк официально выходящий в альфа-бета видах. Притом накрученная функциональностей, которая особо никому и не нужна.
Во-вторых, не стоит по одной-двух программах делать выводы о отрасли в целом. Во времена MSDOS, были свои глюкавые монстры.
PD>Мне тут VladD2 упрек такой кинул — дескать, писать надо , не PD>слишком думая об эффективности, а потом узкие места можно оптимизировать.
Подпишусь.
PD>Теоретически — совершенно безупречное рассуждение. А практически — это PD>верно, если Вы заранее какой-то целью задаетесь — по памяти не более... PD>или по времени не медленнее ... Если нет — никто и не будет оптимизировать, PD>потому как совершенно непонятно, что и зачем. Работает каждый модуль раз в PD>5 дольше , чем можно было бы, памяти кушает раз в 5 больше, чем надо было PD>бы — что тут оптимизировать? Так и должно быть, все нормально сделали!
Будет. Важно даже не то, что в бумажках написано. Важно доволен ли пользователь программы. И хорошо ли ты написал, плохо ли, — клиент всегда прав. Ты можешь выжать 100 процентов оптимизации, но клиенту будет этого мало. И нравится тебе или не нравится, считаешь ли ты это нужным, или не считаешь, ты обязан это сделать. И тут никого не волнует даже то, умеешь ли ты оптимизировать, или не умеешь. Не умеешь, с голоду помрешь.
PD>В результате получаем некую самодвижущуюся повозку размером с аэроплан, PD>ставим на нее ракетный двигатель, запускаем — едет! Едет ведь! Со скоростью PD>60 км/час. Ну вот это и есть настоящий аэроплан, в серию его и пусть PD>по дорогам ездит. А когда этим разработчикам объясняешь, что аэроплан PD>должен не ездить, а летать, и не 60, а 900 км/ч давать, а если Вы автомобиль PD>делали, то он и при двигателе внутреннего сгорания должен эти 60 (а то и 120) PD>давать, да и размерами должен быть раз в 20 меньше — удивляются, чего, мол, PD>привязался! Ездят же на нем, чего тебе надо!
Аналогия неуместна. Важно насколько клиенту важно чтобы он летал. Зачастую заказывают атомную подводный крейсер, а тебе выкатят Ту155 с 5 подводными винтами. И вроде двигается быстрее чем нужно. И летает, что не заказывали. И вроде винты красивые и их больше чем нужно. Но не плавает. Ну не успели научить.
PD> Создается впечатление, что рост быстродействия процессоров несколько PD>замедлился. Может быть, я не прав, но мне кажется, что мы подошли к некоторому PD>пределу, и если не последует технологического прорыва, то скорость сильно расти PD>не будет. Еще раз — может быть, я не прав. Кстати, о памяти пока в этом плане PD>говорить не приходится.
Не согласен. Уже вверх перестали развиваться такими темпами. Зато начали развиваться вширь.(двухядерные процы) PD> Но так или иначе — этот предел есть. Очень уж четкие физические PD>законы здесь действуют, их не обойдешь. Раньше или позже, но бурный рост PD>мощности ПК заменится если не стагнацией, то более или менее плавным изменением, PD>на проценты, а не в разы.
Это только что обсуждалось в соседнем топике.
PD> Не согласны ? OK, кто из вас взялся бы написать "Turbo Pascal 1.0" PD>образца 2005 года? Который будет работать в такой маленькой памяти — 512 Мбайт PD>и на таком медленном процессоре с частотой всего 3 GHz ? Боюсь, что Вы PD>потребуете для этого 16 Gb памяти и не менее 30 GHz . Вы же прекрасно знаете, PD>какие ресурсы для чего требуются, поэтому оцените их для этой задачи и получите PD>16 Gb и 30 GHz, А где их взять? Впрочем, нет, не потребуете. Вы даже задачу PD>такую не поставите — Вам она и в голову не придет: Боюсь, что мы даже и не PD>узнаем, что могло бы быть написанным, если бы это эффективно делалось...
Не забывай. Компилятор Турбо-Паскаля практически полностью написан на ассемблере. И не от хорошей жизни. А письмена на ассемблере, даже тогда считались делом излишним и слишком крутым для повседневных задач. Попробовал бы ты описать паскаль в самом паскале. Тогда бы ты точно не запихнул это в 64 кил.
А на 512 легко. Но вопрос в другом. Если ты пишешь компилятор паскаля, то можно и в мег запихнуться. Но если ты будешь писать сервер приложений, и уместился в мег, то тебя в первую очередь должны выгнать. И я буду первым бежать и махать поганой метлой. Если тебе дали компьютер, с гигабайтом памяти, и с несколькими процессорами, то повышай эффективность используя все что тебе дали. Делай большие кэши, пользуй несколько потоков.
PD> Ну и к чему автор призывает, спросите Вы ? К поголовному возврату на PD>ассемблер PD>и к 64 Кбайтам ? К отказу от того пути, по которому сейчас пошло развитие ?
Знаешь, мне как программисту хочется вернуться туда. Все было интересней. Компы знали как свои пять пальцев. Но вот как главу семейства — ни в коем случае.
Я живу в своем времени. Если понятия эффективности изменились, то я их принимаю. Я делаю программный продукт, а не поделку для удовлетворения собственного эго. Я могу написать Паскаль на 64 килобайта. Но не буду. Не потому что это сложно. Ничего сложного в этом нет. Нужно просто уметь выжимать 100 процентов из компилятора и архитектуры. Это просто никому не нужно. Времена 64 килобайт прошли. Сейчас стало легче жить. И это хорошо.
PD>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>это возможно!
Слишком абстрактно. Надо сначало описать, что такое эффективность. Именно в нынешние дни.
E>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>>это возможно!
E>Имхо, пока за скорость разработки платят больше, чем за скорость работы заказанной программы, этот призыв останется "гласом вопиющего в пустыне".
Спасибо автору топика, за то, что вернул ко временам моей программисткой юности Присоединяюсь.
В качестве продолжения посмотрите, коллеги, вот эту статью одного ассемблерщика http://www.wasm.ru/article.php?article=onebyte. Не перевелись еще богатыри
Приходиться заниматься гадостью — зарабатывать на жизнь честным трудом (Б.Шоу)
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Нет, оверлей — это нечто иное. Я этим на СМ-4 и ЕС-1022 занимался, это вполне легальное действие, даже ассемблер не требуется. А самоубийство только на ассемблере делалось, даже ИМХО не на ассемблере тогда, а просто в кодах.
Да уж. Я тогда маленький был. Слышал о монстрах которые для того чтобы понять программу переписывали с ассемблера на коды.
PD>Чудно. А могу я эти сервисы безболезненно удалить, и освободить Мбайт так 50-60 ? Немного — получится, а остальные, увы, обязательны для системы. А мне, в общем, все равно, как это называется, ядро или сервисы, лишь бы занимали они поменьше.
Тут конечно фигня творится. Когда новую функциональность с исправлением ошибок смешивают. Но отрицать то, что увеличение функциональности сервиспаками и требования к памяти строго пропорциональны, нельзя. Таже NT4 — с последними сервис паками мег 100 занимает оперативы. Если отрубать ненужное, то можно и сильно сократить. Вопрос только в том, что инструментов недостаточно.
GZ>>Если пользователь будет одновременно работать с моей программой, с 10 вордами, 50 акцессами, и 30 экселами одновременно, то у него моя программа будет тормозить. Скажи мне, это я в этом не виноват?
PD>А какое это имеет отношение к тому, о чем я говорил ? Если машина загружена сверх ее реальных возможностей — конечно, ты не виноват. А вот если реальные возможности машины позволяют загрузить 10 копий твоей программы (без вордов и эксцелов), будь она эффективно написана, а она написана так, что и 3 копии тормозят — виноват ты.
Я бы не стал так говорить. Можно просто программы классифицировать:
1. Резидентные программы на машинах пользователей. Они действительно должны быть компактными, не должны забирать много ресурсов компа, и не мешать пользователю выполнять его основную работу.
2. Резидентные серверные программы. Строго наоборот. Они должны адаптировать полностью ресурсы компьютера ради своей эффективности. И никак иначе.
3. Пользовательские программы. Наверно этот класс программ ты и имел ввиду. Вот именно это и есть путь для компромиса. И компромисс между функциональностью и ресурсами. Если функциональность нужная, и она требует достаточно ресурсов, то пользователь не будет возражать, по опыту знаю. Если в требованиях к программе не записано что попутно должны генерится сцены 3D Studio Max, то ему несложно будет выгрузить ее, или понять о том, что это была именно его ошибка. Но вот если функциональность ненужная, а требует достаточно ресурсов, то здесь и я сильно возмущаюсь(а такое на каждом шагу ). Но существует еще вопрос, что значит избыточность ресурсов? Если моя программа занимает на N мегабайт больше, и при этом я уверен что количество ошибок(которые есть будут и полностью их поубивать нельзя) значительно меньше, то я займу эти N мегабайт. В принципе, это и есть некоторая цель Net Framework. Пользовательские компьютеры сейчас избыточны. У них значительно больше памяти чем нужно, и процессоры значительно быстрее чем нужно для большинство задач. Но адаптируя избыточные ресурсы компьютера к цели уменьшить количество ошибок программ, я делаю больше для пользователя, чем таже программа — хоть и маленькая но ненадежная.
PD>Ты можешь сформулировать когда программу можно считать избыточной?
PD>Попробую. PD>Программа избыточна, когда она PD>1. Использует памяти больше, чем требуется. PD>2. Загружает процессор больше, чем требуется. PD>3. Хранит на диске файлы большего размера, чем требуется.
PD>А требуется — по характеру задачи.
Все это ресурсы избыточны для повседневной работы. Мне не жалко 20 мегабайт — если у меня их 500. Если у меня есть вариант, что адаптировав эту избыточность я повышену эффективность даже не программы. а разработки, я ею воспользуюсь.
PD>>>Или вот другой пример — с умножением матриц GZ>>Вроде дошли до того, что здесь кэш процессора играет слишком большую роль.
PD>Дошли до того, что здесь виной перегрузка в кэше оверхеда на класс массив.Но по мне хоть кэш, хоть процессор, хоть винчестер, хоть дух святой. Не желаю я причин знать , а просто факт констатирую — машина это может в несколько раз быстрее делать, значит и должна делать!
Для данной конкретной задачи, это корректное замечание. Net — не очень подходит под числодробилки. Правда это можно сделать за пределами Net.
GZ>>Это взгляд со стороны. Разработчики все понимают. Но понимают и другое. Здесь уже несколько раз обсуждалось. Ошибиться в том, что ты неправильно определил место торможения, потратил много времени и сил на работу которая не нужна, значительно хуже. Поэтому лучше сначало сделать, а потом заниматься выявлением узких мест. А также оптимизацией памяти, если ее оказалось недостаточно.
PD>Ничего у вас не получится. Потому что эти узкие места вы, может, и найдете, а вот общий уровень все равно с оверхедом будет. Там Мбайт, здесь Мбайт — в итоге 100 Мбайт и виновных нет.
Нет. Не том и дело.
1. Если ты получил понятную программу, достаточно маленьку по исходным кодам, которую прочитает любой ребенок, и которая представляет вверх искуства программирования на ООП, это совсем не значит что она есть эффективна в плане использования памяти и процессора. Даже сказал бы наоборот. Но вот то, что в ней ошибки локализованы, сопровождать ее легко — это факт. После этого ее доводят до требуемого уровня производительности. Это делается легко, поскольку дизайн программы легко сопровождаем. Но это приводит к усложнению дизайна программ. А иногда и архитектуры.
2. Если ты начал предполагать в процессе построения программы, что вот здесь есть узкое место, которое написать оптимально, то
Во — первых, ты можешь ошибиться, это происходит часто, особенно на уровне конкретного программиста большого проекта. Например предположил что здесь надо бы переписать чтобы использовалось значительно меньше тактов процессора, но оказалось что сюда программа зайдет только один раз. И нагрузка на проц, в данный момент никого не волнует. Или когда компилятор делает оптимизацию за программиста, но он об этом не представляет, и тратит даром время при этом мешая компилятору. Это хорошо проявилось например в разности времени здесь
. Оптимизация вполне корректна со стороны программиста, только компилятор уже это сделал.
Во — вторых, ты увеличиваешь сложность дизайна тогда когда он наиболее важен. В результате, при добавлении функциональности увеличивается количество ошибок. IMHO Это более тяжко чем неэффективное использование ресурсов.
Вобщем, мое мнение, что оптимизация программ по используемым ресурсам, должны проходить в 3 плоскостях:
1. При построении архитектуры. Мы еще видим все проблемы в комплексе, и наиболее крупные можем сразу решить.
2. Алгоритмическая оптимизация. Неэффективный алгоритм на порядки хуже неоптимизированного кода.
3. Оптимизация готового продукта под конкретные требования пользователя. Свое мнение я уже описал.
PD>А у ICQ вообще когда-нибудь не-беты были ? У меня что-то впечатление такое, что она только из бет и состоит
Нет, еще альфы. По моему — релизы там не бесплатные. Хотя могу ошибаться.
GZ>>Будет. Важно даже не то, что в бумажках написано. Важно доволен ли пользователь программы.
PD>Пользователь доволен. Вполне. И если он у тебя один — решай с ним все проблемы. А вот когда речь о продуктах, используемых в миллионах копий идет — тут задавать вопрос, доволен ли пользователь — все равно, что спрашивать, оуениваете ли вы положительно работу ГосДумы . Отдельно одной программой доволен, другой — доволен, третьей доволен, все вместе запустишь — недоволен. Жалуйтесь кому хотите, хоть господу богу.
Пользуйся альтернативами Я понимаю что в случае крупных монополистов — такое плохо проходит. Слишком высока сложность программ. Но нельзя так говорить о всей отрасли. Пользуются же мирандой вместо аськи.
PD>Бывает и такое. Как в известном анекдоте, как ни собираю, а пулемет получается. Но почему аналогия неуместна — не понял.
Потому что важно чтобы летал, а не с той скоростью которую пользователь не заказывал. В старое время бесшабашных программистов одиночек, они могли плавать, и даже нырять. Но летать не получалось. Сам такие программы писал, грешен.
Так что главное достигнуть цели. Если цель не достигнута, то уже ничего не важно.
GZ>>А на 512 легко. Но вопрос в другом. Если ты пишешь компилятор паскаля, то можно и в мег запихнуться. Но если ты будешь писать сервер приложений, и уместился в мег, то тебя в первую очередь должны выгнать. И я буду первым бежать и махать поганой метлой. Если тебе дали компьютер, с гигабайтом памяти, и с несколькими процессорами, то повышай эффективность используя все что тебе дали. Делай большие кэши, пользуй несколько потоков.
PD>Если я это сделаю, и все же уложусь в мег, ты меня все равно выгонишь ? Если я вместо буфера в несколько мег, в котроый все читается, использую MMF, в котором доступ будет только к тому, что реально требуется — тоже выгонишь ?
Да. Я вполне представляю весь процесс сооружения такой программы. Если ты потратил время на то, чтобы адаптировать решение на меньшие ресурсы, когда я знаю что ресурсы заказчика(или предполагаемого заказчика) значительно больше, то безусловно. Ты проделал работу, которая никому не нужна. Мало того, ты усложнил сопровождение программы. Для программ класса серверов приложений — я не вижу исключений из этого правила.
Здравствуйте, savaDAN, Вы писали:
DAN>Давайте разберемся с критерием "насколько это возможно", судя по тому что подход используемый в индсутрии выраженный владом: "оптимизируй только там где это необходимо" смею предположить что вы проповедуете подход "чем больше тем лучше"?
Я абсолютно согласен с ортимизацией "где надо", речь не об этом. В исходном посте посте говорилось о тенденции, о появившихся привычках и том, что понятие "оптимальный" просто забывается, уходит вслед за 1Mhz компами и 640Кb памяти. И что эта тенденция очень может выйти боком в свете физических пределов GHz и Gb.
Дарней wrote:
> Научить обычного, не озабоченного "оптимизацией-везде-где-можно" > программиста оптимизировать программы куда проще, чем научить > "байтовыжимателя" писать нормальный и понятный код.
Кто сказал, что хороший оптимизированый код — непонятен? Код той же
Miranda читается без всяких проблем, хотя она и не жрет мегабайты.
> Потому что второй всегда будет искать, как в .NET обнулить поля > структуры с помощью ZeroMemory (да-да, это намек ) — вместо того, > чтобы проектировать архитектуру. Да еще и считать окружающих идиотами, > потому что они не понимают, как же это важно — обязательно залезть на > нижний уровень по самый локоть.
Опять же, оптимизация — это не значит копание в машинных кодах. Нужно
просто следить, чтобы не было явных ляпов, где время/память тратится зря.
Да в чем же я ошибаюсь? Везде, где это возможно, все стараются делать проще, а не эффективнее.
Причины непереписывания на .net word-а по-моему очевидны. К неэффективности .net никакого отношения они не имеют.
И вообще — я бы поставил вопрос иначе — пока ратующие за эффективность кода будут ковыряться в своем низкоуровневом коде, использующие windows forms (или VB) коллеги будут успешно сдавать заказчику один проект за другим. Замечу — результат их труда неизменно будет отвечать заявленным требованиям по эффективности.
Поделюсь одним жизненным наблюдением.
Моя фирма использует в своей работе инструментальные средства и подходы, по сравнению с которыми между .net и машинными кодами разницы почти не заметно.
Как-то раз пути одного из наших проектов пересеклись с проектом некой третьей фирмы, которая все по-мужицки делала на с++. Год за годом, версия за версией. Они с этого проекта, собственно, и кормились (насколько я понимаю).
Когда руководитель группы разработки этой фирмы во время сравнительных испытаний возможностей их системы и того, что было сделано тремя нашими разработчиками за пол-года, увидел наш вариант — у него натурально дрожжали руки. У человека началась форменная истерика — потому что от очень четко понял свое место в этой жизни. И место своего подхода к разработке ПО, соответственно.
Кесарю — кесарево, а слесарю — слесарево. И пытаться привинтить к прикладному программированию высокие идеалы экономии бесценной conventional памяти — не стоит.
Здравствуйте, Pavel Dvorkin, Вы писали:
D>>А как вам вот такой тезис, что программа просто должна быть достаточно xxx? D>>Не надо выделять потребляемую память и быстродействие в отдельную категорию. Программа должна быть достаточно во всем и, в идеале, одинакого. Далее неупорядоченный список: достаточно функциональна; достаточно удобна; достаточно устойчива; достаточно мало жрать память; достаточно быстро работать;
PD>Если бы мы были в однопрограммной системе — готов согласиться. А в многопрограммной — нет. Потому как отдельная программа может быть вполне достаточна, а все вместе они едят ресурсов немеряно и тормозят.
PD>Кстати, сформулируй критерий достаточности, если можешь.
Для начала честно признаюсь с неспособности его сформулировать, но могу показать, где как я думаю стоит его искать в конкретных случаях.
Во первых полностью согласен с мыслями
Glebz о достаточной оптимальности. Особенно с его классификацией и походом к оптимизации.
Далее предлагаю забыть о том что работа это не только возможность кушать, но еще и сточник кайфа и способ "поддерживать форму". И посмотреть на "достаточно" только с точки зрения бизнеса.
Во-первых наше место в делании денег на софте: Делает их кассир, в тот момент когда приходит покупатель. А приходит он потому, что отдел PR удачно прорекламировал продукт и покупатель не только узнал, но еще и решил купить. А вот теперь наше место — помочь PRщкам делать свою работу лучше. Если бизнес делается не на продаже софта, немного меняются детали моего рассуждания, но общая идея таже — наше дело делать софт, достаточно востребованный пользователем. Достаточно в смысле бизнеса.
Теперь, кто же тот самый пользователь, для которого надо быть достаточным? Ответ — тот же для кого стараются PR. Тут пользователи делятся на две группы:
1. Кто уже выбрал. Их надо удержать, новая версия (патч) должена быть достаточна, что бы пользователь не взял другой продукт и должена быть выпущена достаточно быстро.
2. Кто про продукт знает, но не пользуется. Соответственно достаточно чтобы потенциальный пользователь стал действительным.
Ксати предположения о target group и цене на продукт могут очень помошь всести многопрограммную систему к "квази" однопрограммной.
Сколько ресурсов у предполагаемого пользователя? Какие сколько из них заняты его типовыми программами? — Остальное только для нас
Сколько пользователь заплатит за наш софт? А сколько за апгрейд, что бы не тормозил?
Девелопер должен думать о том как с наибольшей пользой потратить свое рабочее время. В частности, если плохо известно для кого стараемся, то очень может быть, что стоит вообще ничего не кодить, а узнать это.
Возможна ситуация, когда начальник имеет другое представление о приоритетах (в просторечие — начальник дурак ), а рассматриваем мы ситуацию с позиции хорошо покушать, и удовлетворить вообще-то надо начальство. Тут два варианта (кроме увольнения). Донести свое видении до начальства. Или получать кайф от качественного выполнения заказанной работы, в конце-концов, может он и прав и в любом случае это его ответственность.
PD>Удобство UI прямого отношения к эффективности обычно не имеет. А вот чистота и последовательность архитектуры отнюдь не требует применения неэффективных методов. Скорее наоборот — скажи кратко, но хорошо (К. Прутков)
Не соглашусь по обоим пунткам. Тривиальный пример — это выбор платформы (процессорный код vs VM, различные языки — различного качества компиляторы/VM`ы).
Архитектура может быть достаточно гибкой для оптимизации, но при этом излишне сложной, если оптимизация не потребуется. И наоборот, очень удобной, но местами эффективные решения придется делать кривостью. В первом случае получаем много скорости мало фич, во втором — наоборот. Конечно замечательно, когда "кратко, но хорошо", но бывает озарение не пришло...
C UI теже проблемы. Все время стоишь перед выбором, усложнять реализацию или использовать не эффективные решения. Например, хочу показать всегда актульную информацию -> паттерн observer -> что наблюдаем? И тут часто оказывается, что следить за всем подряд существенно проще чем только за тем, что необходимо. А если завтра после небольших изменений необходимого станет больше?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Мне тут VladD2 упрек такой кинул — дескать, писать надо , не PD>слишком думая об эффективности, а потом узкие места можно оптимизировать. PD>Теоретически — совершенно безупречное рассуждение. А практически — это PD>верно, если Вы заранее какой-то целью задаетесь — по памяти не более... PD>или по времени не медленнее ... Если нет — никто и не будет оптимизировать, PD>потому как совершенно непонятно, что и зачем. Работает каждый модуль раз в PD>5 дольше , чем можно было бы, памяти кушает раз в 5 больше, чем надо было PD>бы — что тут оптимизировать? Так и должно быть, все нормально сделали!
А как вам вот такой тезис, что программа просто должна быть достаточно xxx?
Не надо выделять потребляемую память и быстродействие в отдельную категорию. Программа должна быть достаточно во всем и, в идеале, одинакого. Далее неупорядоченный список: достаточно функциональна; достаточно удобна; достаточно устойчива; достаточно мало жрать память; достаточно быстро работать; если проект после 1.0 не планируется отправить в архив то достаточно сопровождаема; и т.д. А скорость эскадры равна скорости самого медленного корабля.
Я ни в коем случае не призываю не думать об эффективности, не искать всегда и везде лучшие подходы и алгоритмы. Я предлагаю не думать об этом больше/чаще, чем о, например, удобстве UI или чистоте и последовательности архитектуры. Не забывать, что как бы быстро прога не работала, она будет бесполезна, если пользователь не сможет решить с ее помощью свои задачи.
Что касается непонимания в глазах начинающих, то это непонимание бывает в всех вопросах и оптимальность далеко не единственный из них, хотя, похоже, для Вас лично, самый больной. Но тут для того и нужен Учитель, что бы проводить Ученика его (Ученика) путем в ближайший тупик и... оставить его там подумать.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>это возможно!
Читал. Плакал. Вспоминал статью Саттера “The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software” — там тоже про то, что закон Мура уже не тот, что был раньше
Однако, в наше время таки оптимизировать всё до последнего байта есть непозволительная роскошь. Моё время как разработчика несравненно дороже времени процессора и оперативной памяти.
Я приведу пример из собственного проекта. У меня есть изображения букв в матрице 32×64, и время от времени мне приходится сравнивать их с генерируемыми в процессе работы программы изображениями в аналогичной матрице. Если бы я не поддался на идею коллеги закодировать каждую строчку пикселов DWORD’ом, и хранил их в 8-битных bitmap’ах — у меня бы для сравнения использовалась библиотека Intel Performance Primitives, тщательно вылизанная разработчиками из Intel’а под все их процессоры. И по скорости, я уверен, это было бы быстрее, чем написанные моими не идеально прямыми руками циклы. И в части внедрения изменений в код это было бы более поддерживаемо, чем эта побитовая арифметика и магические функции подсчёта битов в двойном слове.
Пишите свои программы понятно, господа! Если использование показывает, что память — узкое место, найдите 10% кода, которые используют 90% памяти. Если использование показывает, что узкое место — процессорное время, найдите 10% кода, которые работают 90% времени. Premature optimization is the root of all evil, хотя и premature pessimization тоже is the leaf of no good.
PD>+-. И да, и нет. Потму как этих серверных программ на машине может быть несколько, и лучше бы им не брать все ресурсы компьютера, а то придется по серверу на каждую программу иметь.
Исходим от затрат, часто гораздо дешевле поставить еще один сервер.
PD>Если я напишу это же без FrameWork, алгоритм будет тот же, эффективность выше и памяти меньше, то это будет лучше.
Если Вы будете писать это дольше то "лучше" это не будет скорее всего. Опять слова "эффективность", "лучше".
В чем измеряеться Ваша "эффективность", в чем измеряется Ваше "лучше"?
В разных контекстах они могут означать противоположные или просто разные вещи. >А то, что на FrameWork ошибок будет меньше — не уверен. Не все сводится к мемори ликам и некорректным индексам.
Зато это достаточно трудно обнаружимые баги, ибо не всегда вы за несколько минут найдете, откуда память потекла, а битый указатель может проявится совсем не в том месте, где его "сломали". Это могут быть вполне разные программные модули. Если машина помогает избавиться от технических багов, почему б не использовать эту возможность?
PD>Большинство программ таково, что они используют значительно больше памяти и процессорного времени, чем им в действительности нужно. Поэтому программ, которые могли бы при оптимальной эффективности использовать память и процессор, не существует (почти), так как при нынешнем стиле написания программ им нужны намного большие ресурсы, которых пока нет.
Кто определил сколько программе "в действительности нужно"? Бог Программистов? Опять какие то непонятные идеалы? Аппелирование к абсолютным истинам? Их несуществует, тем более в программировании, имхо.
PD>Во-во. Тебе надо 20, а берешь 40. Мне надо 50 — беру 80. Ему надо 100 — берет 150. А этому надо еще 100 — пошел вон, памяти больше нет. PD>Да, увы, это так. Ты сделаешь быстрее, не спорю. И сэкономишь несколько К$ на своей зарплате. А в итоге 100,000 пользователей потратят несколько сотен тысяч $ на память, которую твоя программа заняла и не использует.
Закон рынка — пока клиент готов платить, пусть платит.
Какое мне дело до того сколько они платят, если они готовы это делать? Главное, что мои доходы от этого повышаются.
Извините за некскромность, вы боретесь за какую то абсолютную правду?
PD> Пока не знаю что. И не убедишь его, что это , м.б. не лучшее решение.
Вот когда будет известно что, то и можно говорить о "лучшем решении". Опять же, никто не запрещал юзать разные технологии в одном проетке, адекватные конкретной подзадаче проекта.
И, главный, имхо, вопрос: А зачем вам убеждать заказчика? Что лично ВЫ(ваша команда, компания) от этого получает? Прошу не воспринимать это как наезд, это вопросы, которые я бы сам себе задал, если б пришлось убеждать в чем то заказчика. Кстати говоря, заказчик не всегда знает, что ему конкретно надо, для этого есть этап сбора требований
PD>Ничего ты не соптимизиуешь. Не ты лично, а те, кто к эффективности не привык. Им и в голову не придет, что это все на 20 Мб может меньше требовать.
Уже было выше, им это прийдет в голову, когда начнут падать продажи продукта и клиенты побегут к конкурентам. Рынок — саморегулируемая система.
Здравствуйте, Pavel Dvorkin, Вы писали: PD>Хотел было прекоатить — так не получается.
PD>Твое ? Тогда смотри дальше.
Да. PD>Где здесь дают эту самую длину ? Ответь, пожалуйста.
Я показывал. Павел, я уже начинаю уставать. Я попросил тебя дать примеры того, откуда берутся строки без длины. Ты привел пример с едитом — неправда, он отдает длину. Ты утверждал, что даже если бы длина была, все равно ее пришлось бы вычислять — неправда, есть невычисляющие конструкторы. Теперь мы наконец переходим к той части аргументации, которая не является банально неверной.
PD>Где длина строки в текстовом файле ? Где она там хранится ? Там нет и нуля, конечно — по известным тебе историческим причинам. Но ограничитель там есть. (0D0A).
Ну и что? Как это нам помешает получить длину? Достаточно сделать вот так:
long initialPosition;
long finalPosition;
initialPosition = ftell(stream);
char line[4000];
fgets(line, 4000, stream);
finalPosition = ftell(stream);
int len = finalPosition - initialPosition;
Вуаля! У нас есть длина строки от fgets без вычисления. PD>Где она после того, как fgets вернула строку?
В указателе файла, с которым работала fgets. PD>Если мы будем делить источники на основные и неосновные, то спор уйдет в никуда.PD> Ты приводишь случаи, когда ее дают. Я — когда нет. Для того, чтобы ты был прав — необходимо, чтобы давали всегда. В противном случае твое утверждение необоснованно. Теорема, для которй есть хоть один опровергающий пример, опровергнута.
Павел, именно этим и отличается академический подход к разработке программ от прикладного. С прикладной точки зрения совершенно несущественно существование источников, которые передают информацию с потерями. Важнее — возможность воспользоваться нормальными источниками. Напомню, что ты пока не дал ни одного примера источника, который бы не позволил получить информацию о длине строки, кроме консоли.
Что это означает? Что пока что полезность строк без длины сводится к программам, интенсивно работающим с консолью. Все остальные программы, получается, только выигрывают от наличия длины.
>>Также не относящимися к делу я считаю все рассуждения о наличии нулевого окончания в классах строк с длиной. Они, очевидно, нужны для передачи в устаревший код, который не способен использовать уже доступную информацию о длине строки.
PD>Нет. Они нужны для передачи этих строк в качестве входных аргументов этих самых винапи функций.
Да-да. Я и говорю — см. выделение. PD>Я, кстати, об этом написал, но ты предпочел на эту часть моего письма не ответить, а просто выкинуть ее. Можешь все же ответить?Формулирую прямо
PD>Если в винапи используются строки с длиной, почему почти ни одной функции винапи эта длина не передается ? Почему они принимают только char* (wchar*) и вычисляют эту длину у себя внутри сами ?
Значительная часть функций винапи придумана около 20 лет назад. Конечно, далеко не все из них были продуманы. В некоторых из этих функций длина просто не очень-то и нужна — вполне можно построить достаточно эффективный алгоритм и без нее. По крайней мере, достаточно эффективный в большинстве случаев. Ну вот как в PathCombine. Длина им не нужна — я и так могу спорить, что они просто тупо копируют строки одна за другой в отведенный буфер, почти как strcat. При этом они проверяют, не наступили ли на ноль в конце этого буфера, в целях безопасности. В случае передачи буфера недостаточной длины мы узнаем об этом гораздо позже, чем в случае строк-с-длиной. Но этим явно можно пренебречь — вряд ли имеет смысл оптимизировать производительность обнаружения ошибок.
PD>И как следствие из этого — еще один вопрос
PD>Почему, если они так делают и это правильно — когда я это делаю, это неправильно ?
Из неверной посылки следует все что угодно. Они так делают и это неправильно. PD>Их выход — мой вход, мой выход — их вход.
S>>Действительно, в ВинАПИ есть функции, которые не позволяют получить длину строки без доп. затрат (как правило, в таких случаях можно получить точную верхнюю границу длины строки — а это позволяет нам все еще писать безопасные, хотя и не столь эффективные, алгоритмы).
PD>Хм, а ведь в том примере, с которого весь сыр-бор разгорелся (с sprintf) я же битый час доказывал, что у меня есть эта самая точная верхняя граница.
Это какая? У тебя не было никакой верхней границы. У тебя была наивная вера в существование верхней границы. А когда я говорю про точную верную границу, я говорю вот про что:
Допустим, мы воспользовались функцией fgets:
void main( void )
{
FILE *stream;
char line[100]; // ВНИМАНИЕ! У нас буфер размером в 100 символовif( (stream = fopen( "fgets.c", "r" )) != NULL )
{
if( fgets( line, 100, stream ) == NULL) // какое совпадение - здесь тоже n = 100
printf( "fgets error\n" );
else
printf( "%s", line); // и это означает, что здесь line не длиннее 100!
// добавим строчку в пример MSDN:char line2[30];
fgets(line2, 30, stream);
char line3[40];
fgets(line3, 40, stream);
fclose( stream );
}
}
Итак, здесь мы имеем точную верхнюю границу для суммы всех длин: она равна, очевидно, 168. Мы можем спокойно использовать для конкатенации буфер этого размера. Не потому, что где-то в БД (внешней по отношению к нашей программе!) есть размер поля, и не потому, что оператор поклялся не засыпать на пробеле, а потому, что выполняются некоторые инварианты. Функция fgets так удачно написана.
PD>Но это вызвало твою негативную реакцию. Получается, коль винапи функции могут эту границу дать или ты как-то иначе оценить можешь — им доверять можно, а если я их даю — так нельзя ? Почему ?
Потому, что ты свое значение границы высасываешь из пальца, а винапи поддерживает с математической точностью.
PD>Охотно допускаю, что он не менее эффективен. Но какое это к делу имеет отношение ? И винапи PathCombine можно переписать, добавив ей длины и сделав безопасной. Но этого нет. В винапи. А то, что это есть или может быть в C# — я и не спорю.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel Dvorkin, Вы писали:
Д>>кстати говоря, во многих серьезных конторах за использование любой функции из семейства printf нещадно бьют по рукам. И даже более серьезно — по кошельку.
PD>А это от ситуации зависит. В том проекте, в котором я участвовал, мне все было разрешено, кроме одного — низкой скорости работы. Занял бы на диске лишний Гбайт — простили бы. ОП использовал бы в 2 раза больше, чем надо — тоже простили бы. А вот уложиться я должен был в 100 мсек. Кровь из носу. Потому что если 200 мсек займет — это кончится просто тем, что данный образец будет снят с обработки по нехватке времени, а тем самым число необработанных образцов увеличится. А обрабатывается таких образцов в день примерно 30,000 только на одной машине, и на каждый образец дается не более 3 сек. И за это время к моему ПО делается 10-15 запросов плюс, естественно, то время, которое нужно на оставшуюся часть, а оно есть примерно 60% общего времени. А машин примерно 1000. Борьба шла за каждый процент. И мне все прощалось, только бы быстрее. И сделал я им вместо 100 мсек 20-30 мсек, и были они в полном восторге
PD>А лишних Гбайтов я , кстати, не использовал. И лишней ОП — тоже. Ну разве что самую малость — буфер там был один с запасом в 64 Кбайта
Зато как же обломно после таких проектов формочки на JSP рисовать и SQL запросы сочинять!
Блин, словами не передать.
Зато антураж какой! Рефакторинг, юниттестинг, код ревью, баг трекинг, UML, XML, SQL,... память нынче не ресурс... давай, давай, сроки горят... память нынче не ресурс... давай, давай, все должно было работать еще вчера... память нынче не ресурс... Об эффективности программ
Просто, как говорится, кто девушку обедает — тот ее и танцует. И в разработке ПО, бог — заказчик. А ему, насколько я знаю, зачастую не нужно наилучшее решение, ему нужно, чтобы быстро, более-менее качественно, документированно, сопровождаемо...
Здравствуйте, Cyberax, Вы писали:
C>Кто сказал, что хороший оптимизированый код — непонятен? Код той же C>Miranda читается без всяких проблем, хотя она и не жрет мегабайты.
А кто вообще сказал, что он такой уж оптимизированный? Если ты прикрутишь к ней кучу плагинов, чтобы сравнять по всем функциям с аськой — уверен, жрать она будет ничуть не меньше. К тому же глючит она не по детски — хотя и сам ей давно пользуюсь, ибо перегруженная ненужными функциями аська меня совсем достала.
Так что — за всё надо платить.
C>Опять же, оптимизация — это не значит копание в машинных кодах. Нужно C>просто следить, чтобы не было явных ляпов, где время/память тратится зря.
Ты можешь точно сказать, где проходит граница между "явными" и "неявными" ляпами?
Буду краток: писать код надо так, чтобы из него можно было получить максимальную денежную прибыль.
Лично я признаю только такое правило.
В каких-то случаях, это выская производительность, достигаемая оптимизацией и аккуратностью выбора алгоритмов.
В каких-то случаях, это высокая скорость разработки, с быстрым отловом ошибок, простота архитектуры и грамотное разбиение на классы для дальнейшего удобного сопровождения и модификации. Ситуаций много, поэтому абсолютных правил быть не может. Кроме того, ради чего все делается(т.е. зарабатывания денег)
Уважаемый mrozov правильно написал, что времена любителей позаниматься сексом с компом прошли в индустрии программирования. Энтузиастам и "вольным художникам" не место в индустрии.
Все вышенаписанное — мое имхо.
mrozov,
> ПК> Если у программиста проблемы с ДНК, то лечится это не инструментальными средствами. Инструменты, напротив, должны давать возможности тем программистам, у которых с ДНК все в порядке.
> <...> Не думаю, что стоит вот так категорично говорить о том, что вам должны инструментальные средства.
"Они мне должны" в простом понимании: если средства не соответствуют упомянутому критерию, я им предпочитаю имеющиеся альтернативы, предоставляющие больше возможностей программистам, у которых с ДНК все в порядке, а не облегчающие жизнь тем, у кого в ДНК проблемы в ущерб первым.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, srggal, Вы писали:
S>Так вот во Франции гдн-то в средние века проверяли жениха ( в приличных домах дворянского сословия ), претенденту подавали спелый персик, который он должен был съесть именно фруктовой вилкой и ножом, не теряя собственного достоинства, и непринужденно ведя светскую беседу с будующими родственниками.
В "приличных домах дворянского сословия" людям больше нечем заняться, кроме как заботиться о "сохранении своего достоинства". Потому что работают за них другие. Вот они и придумывали специальные вилки для фруктов, специальные вилки для рыбы и правила, как всё это дело следует употреблять (и не дай бог кому-то взять не ту вилку — фи, как некультурно!).
Нормальные же люди едят так, чтобы было удобно, а не чтобы произвести впечатление на окружающих.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ну и что ? Это лишь говорит о том, что они неверно оценили максимальный размер, только и всего.
PD>Вот давай так
PD>char szTotal[500]; PD>sprintf(szTotal,"%s %s", szFirstName, szLastName);
PD>Программа делается для России. Приведи ситуацию, в которой здесь возможен buffer overrun. Фамилию и имя, please , в студию.
Очень просто. Этот код вызывается из обработчика веб формы регистрации пользователей. Злонамеренный пользователь вводит килобайт мусора. После чего твое CGI приложение делает core dump. Это называется уязвимость.
Еще более злонамеренный пользователь вводит килобайт специального мусора, и твое CGI приложение вносит нужные изменения в системные настройки, а уже потом делает core dump. Это называется эксплойт.
Продвинутый злонамеренный пользователь пишет плагин к известному сканеру сетей, который находит все инстансы твоего приложения в указанном IP — диапазоне.
Таоя компания попадает в списки рассылки "смертельно опасные уязвимости", и ее продукт попадает в черный список. Это называется "банкротство".
Дальше продолжать?
В таком сценарии оказывается значительно дешевле вовремя уволить того, кто использует подобный код, чем любая из альтернатив:
— оплачивать расходы от невовремя обнаруженной уязвимости
— нанять специальных людей, которые станут тестировать твою систему на предмет наличия подобных уязвимостей. PD>Ну и что, опять-таки ? См. мой пример с nScreenArea. Может, оно когда-нибудь и грохнется, на 4ГПикс дисплее.
Еще раз: то, как оно грохнется от целого переполнения, не приведет к исполнению постороннего кода. PD>Но не будешь же ставить под контроль все арифметические операции и на каждую из них писать try-catch из-за того, что при некорректно заданных операндах это может вызвать ошибку ?
Будешь, если тебе дорого твое место работы. Причем кэтчить все места тебе не потребуется: как только придет информация о том, что где-то твое приложение упало, ты получишь нормальный стек трейс, в котором ясно будет указано место падения.
Это позволит тебе очень быстро (по сравнению с анализом дампа) локализовать причины, и либо переписать код (например, используя long вместо int), либо вставить в нужных местах проверки (например там, где принимаются размеры). PD>Если да — то неудивительно, что это будет работать очень медленно. А если нет — то при работе однажды произойдет unhandled exception, и аппарат рухнет. PD>Нет. Не догадываюсь. Потому что любая ошибка может привести к любой наведенной ошибке. А если ты хочешь сказать, что при этом будет неопределенное поведение — так и при неправильных результатах будет то же, не только при выходе индекса.
Нет. Выброс исключения — это НЕ непределенное поведение. Это вполне определенное поведение, которое
PD>А вообще основное различие между моей и твоей позицией ИМХО в том, что ты хорошо знаешь некоторые общепринятые принципы, но рассматриваешь их как догму, которую нельзя переступать, как сказал Sinclair, под страхом смертной казни. Я же считаю, что при определенных условиях может случиться так, что делать придется, нарушая многие общепринятые правила, если это нужно для решения задачи и другого выхода нет. В конце концов лучше написать работающую программу не по правилам, чем по правилам ничего не сделать.
Ты не прав. Если влезть в исходники .Net, то можно увидеть и unsafe, и unchecked. Как раз для того, чтобы поднять производительность. Это не переступание догм, это подробное следование им. Потому, что отмененные такими опциями проверки делаются вручную. Сделать правильную программу быстрой легче, чем быструю — правильной.
Потому, что обо всех небыстростях тебе расскажет профайлер, а о неправильностях — пользователи и хакеры.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Нет. Я просто удивляюсь, что эти ситсемы используют алгоритмы, в которых вместо одного прохода требуется 3, вместо одного блока памяти — 2 и т.д. И мне говорят, что при этом повышается читабельность и легче сопровождение и т.д. Вот это я не понимаю и не принимаю.
Слушай, брось программировать. Береги нервы.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, GlebZ, Вы писали:
GZ>Я бы туда запихнул Миф 9 — Рефакторинг увеличивает производительность кода. Строго наоборот. Он в подавляющем числе случаев уменьшает производительность кода.
Ага. Можно даже закон вывести: для любой программы А, можно написать программу A', которая будет работать медленнее программы А.
Здравствуйте, Cyberax, Вы писали:
C>Ну значит плохо на С++ писали. У нас была обратная ситуация — группа C>С#истов полтора года делала приложение. Оно у них работало, но медленно C>и не особо устойчиво (подумаешь, пара исключений при запске — ничего C>ведь не падает).
C>Поэтому когда мы выкатили заказчику примерно такой же продукт с C>поддержкой OLE2 (то есть наши документы можно, например, в Word C>вставлять) — старое приложение торжественно удалили.
А вот слова Matthew MacLaurin из Microsoft MSX group, который зовет меня туда работать:
The project is an advanced, small-team product – an information manager for the internet age. We started it in research and are now going to ship it. It uses queries as the primary organizational construct – letting users easily build and manipulate queries as first class objects, etc. It also emphasizes tagging and distributed information. We’ve put a lot of work into a very elegant and polished user interface with translucency, drop shadows, seamless compositing everywhere, etc. Our prototype is up and running in C#, and we are now porting to C++.
К чему бы это?
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, McSeem2, Вы писали:
GN>Когда-то спросил старого программера, как писать оптимальные программы. Я то думал, вопрос с подковыркой (оптимизировать по скорости или по размеру можно). А он ответил просто: "упрощай их".
Хотел я в исходном постинге напомнить про один принцип. Потом решил, что введет ненужную игривость
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Кстати, для C++ Степановым в свое время даже был написан набор их 13 тестов, меряющих так называемую abstraction penalty. Для современных компиляторов (Intel C++, Visual C++) abstraction penalty в соответствии с этим тестом, если и проявляется, то "плавает" в пределах единиц процентов.
Здравствуйте, Pavel Dvorkin, Вы писали:
GZ>>2. Резидентные серверные программы. Строго наоборот. Они должны адаптировать полностью ресурсы компьютера ради своей эффективности. И никак иначе.
PD>+-. И да, и нет. Потму как этих серверных программ на машине может быть несколько, и лучше бы им не брать все ресурсы компьютера, а то придется по серверу на каждую программу иметь.
Тут я забыл указать некоторый термин. А именно масштабируемость. Как-то повелось, что каждый смотрит на этот термин со своей колокольни, но рискну дать определение. Масштабируемость — способность увеличивать КПД программы в зависимости от аппаратных средств. То есть, вместо того, чтобы переписывать программу когда не стало хватать пропускной способности, заказчику достаточно купить дополнительную память, или дополнительный процессор, или дополнительный компьютер для кластеризации приложения. У масштабируемых решений практически всегда присутсвует одно свойство. Оно всегда медленнее их немасштабируемых аналогов. Если один или два пользователя, то немасштабируемое приложение масштабируемое порвет как грелку. Но масштабируемость это не просто лейбл. Это действительно очень полезное средство для пользователя. Хреново когда придется переписывать программу, или заказывать другую. И дело не только в деньгах. Дело еще в обучении пользователей для нового продукта, проходить весь цикл установки и настройки. Поэтому использование аппаратных средств — важное свойство серверов приложений.
Архитектор обязан следить за масштабируемостью серверов. Вот если он не следит, то это значит недоучка. Ну а недоучки — это тема других топиков.
PD>Если я напишу это же без FrameWork, алгоритм будет тот же, эффективность выше и памяти меньше, то это будет лучше.
В данном случае да. Но можно сделать и так, в случае большого объема приложения, написать основную программу на Net Framework, а наиболее криминальные алгоритмы написать на unmanaged C++(благо он лучше умеет использовать и управлять ресурсами компьютеров).
PD>А то, что на FrameWork ошибок будет меньше — не уверен. Не все сводится к мемори ликам и некорректным индексам.
Да. И это правда. Не все сводится к мемори ликам. Компонентность тоже провоцирует не делать ошибок. А если приложение большое и многофункционально, то недооценивать компонентность нельзя.
Кроме того, тут стоит говорить не только о Framework, но вообще о языках высокого уровня. Не секрет, что язык высокого уровня генерит избыточный код и избыточно использует память. И чем выше язык, тем труднее поддается оптимизация кода компилятором. В принципе, если взять тот-же STL, то говорить о том, что он по скорости 1 в 1 с кодом написанным вручную на С не приходится. А string вообще кошмар, но зато жутко удобный. И только великолепие и сложность компилятора более менее выравнивает ситуацию.
PD>От ошибок алгоритма меня никакой FrameWork не защащает. Складывать килограммы с метрами (вместо того, чтобы умножать) и там вполне можно, .
От этого никто не сможет защитить. Особенно от непроффесионализма. Но тут никто не властен.
>>Пользовательские компьютеры сейчас избыточны. У них значительно больше памяти чем нужно, и процессоры значительно быстрее чем нужно для большинство задач.
PD>Я бы эту фразу перевернул. PD>Большинство программ таково, что они используют значительно больше памяти и процессорного времени, чем им в действительности нужно. Поэтому программ, которые могли бы при оптимальной эффективности использовать память и процессор, не существует (почти), так как при нынешнем стиле написания программ им нужны намного большие ресурсы, которых пока нет.
Фразы не эквивалентны.
Вообще я бы сформулировал свое мнение так. Функицональность возрастает, и аппаратная часть адаптируется под нее. Или наоборот, аппаратная часть возрастает, и функциональность адаптируется под нее. Не важно какая из них верна.
GZ>>Все это ресурсы избыточны для повседневной работы. Мне не жалко 20 мегабайт — если у меня их 500.
PD>Во-во. Тебе надо 20, а берешь 40. Мне надо 50 — беру 80. Ему надо 100 — берет 150. А этому надо еще 100 — пошел вон, памяти больше нет.
А это уже прямой путь в леса богатые дичью. Поверь мне, везде где я работал всегда думали о компьютерах пользователей. Иначе прогоришь.
>>Если у меня есть вариант, что адаптировав эту избыточность я повышену эффективность даже не программы. а разработки, я ею воспользуюсь.
PD>Да, увы, это так. Ты сделаешь быстрее, не спорю. И сэкономишь несколько К$ на своей зарплате. А в итоге 100,000 пользователей потратят несколько сотен тысяч $ на память, которую твоя программа заняла и не использует.
Обычно если заняла, то использует Если не использует — то это ошибка. Если избыточно использует — ошибка алгоритма.
Пользователей больше занимает полезность программы.
GZ>>Для данной конкретной задачи, это корректное замечание. Net — не очень подходит под числодробилки.
PD>Да ведь нам говорят, что .Net — генеральная линия развития, а те, кому она не нравится — неандертальцы. Вот и мне сегодня заказчик сообщил, что планирует нечто на .Net. Пока не знаю что. И не убедишь его, что это , м.б. не лучшее решение.
Ты сам аргументировать не можешь. Если это сложная программа с множеством взаимосвязей и сложной архитектурой, то да. Это будет хороший выбор. Аналог в виде Java — не сильно отличается.
PD>"У нас никогда нет времени на то, чтобы сделать все как следует, но всегда есть время на переделки"
В сложной программе с множеством модулей, взаимосвязей и народа который все это пытается связать — сразу сделать как следует невозможно. Также как написать программу без багов, это должна быть очень простая задача.
PD>Ну и заявление! Дизайн понятен, сопровождение легко, след-но, оптимизировать будет несложно! А то, что для оптимального решения задачи, возможно, надо не в деталях оптимизировать, а все решение пересмотреть и весь дизайн переделать — это ты не допускаешь ? Совсем другим способом ее решать!
Это — ошибка архитектуры. Тяжелая ошибка. Ее боятся. К ней надо по правильному подходить, либо работать методиками которая не подразумевает первоначальное построение архитектуры(типа XP). Все ХР и построено на том, что функционал достраивается, а следовательно нужен понятный и сопровождаемый дизайн. Ради этого рефакторят. И основным свойством кода является не эффективность в плане выполнения, а именно сопровождаемость. Эффективность в плане выполнения — выравнивают потом. Там вообще не знают и не хотят знать, войдет ли или не войдет данная функциональность в том виде в котором она разрабатывалась на начальном этапе.
GZ>>Во — вторых, ты увеличиваешь сложность дизайна тогда когда он наиболее важен. В результате, при добавлении функциональности увеличивается количество ошибок. IMHO Это более тяжко чем неэффективное использование ресурсов. PD>ИМХО это лечится рано или поздно, а первое — не всегда.
Как раз ошибки вылечить на порядок сложнее. А иногда и невозможно. В непонятном коде значительно сложней найти и локализовать ошибку. Иногда этот код легче переписать чем исправить(такое встречалось), или добавить функциональность. В простом, понятном коде, в котором функицональности все выделены в раздельные сущности, переписать что-то легко. Благо понятно что делаешь.
PD>Да, а вместо Net Framework что предложишь ?
Java. Нельзя от печки требовать, чтобы она стала сново кирпичем. Так и нельзя от net или лиспа, чтобы они управляли ресурсами компьютера также эффективно как это делает более низкоуровневый собрат С++.
PD>Вместо MS Office ?
Тут согласен. Я это и не скрывал.
PD>Опять -таки — все верно, если у тебя единственный заказчик. Ему хоть на 2Gb пиши, если у него их 4. Но я-то о других случаях говорю.
Да хоть тысячи. Перед построением программы, всегда строится примерная картина для кого эта программа предназначена, и что у него есть.
gear nuke,
>>> Излишней является любая оптимизация, которая не направлена на изменение ситуации, при которой система не способна уложиться в определенные в проекте временные рамки на том оборудовании, для работы на котором она предназначена. > > ПК>Только та, которая стоит дополнительного времени при разработке. > > ИМХО любая оптимизация будет стоить дополнительного времени, если проектировать и делать "абы работало".
Не любая. Например, есть выбор: написать сортировку "пузырьком" или использовать библиотечную std::sort. Первое делать дольше и в большинстве случаев работать будет медленнее, чем второе.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
VladD2,
> ПК> И да, и нет. Если переписать, то, может, оно и нормально будет — сейчас, без эксперимента, сложно наверняка говорить Но вот причина, почему они не выпускают Office, перекомпилировав его с помощью MC++ или C++/CLI, заключается как раз в заметно уменьшающейся производительности, которую показывают собранные таким образом приложения Office.
> Это информация от группы Офиса, или умозаключения?
Это информация от группы VC++, сотрудничающей с группой Office в вопросах быстродействия MC++.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Nickolay Ch, Вы писали:
NC>Буду краток: писать код надо так, чтобы из него можно было получить максимальную денежную прибыль.
Хорошие слова. Только не надо под ними подразумевать скорость написания кода. Действительно, существует достаточно много продуктов сделанных тяп-ляп. Да, они выиграли тактически. Они впихнули полуживое решение и получили за них деньги. Только это стратегический проигрыш. Если кто-то увидет такой продукт, то он его запомнит навсегда. И навсегда запомнит, что те-то и те-то пишут не программы а набор ошибок. И исправить это очень сложно. Практически невозможно.
Сейчас существуют в некоторых отраслях такие вещи как портфорлио программ. Есть и тендеры, в которых указываются не только какие программы были сделаны, но и отзывы пользователей. И они кстати зачастую проверяются, так что враки не подпихнешь. Поэтому качество программы обязано быть высоким. Это значительно важнее чем скорость написания программ.
NC>Уважаемый mrozov правильно написал, что времена любителей позаниматься сексом с компом прошли в индустрии программирования.
Нет, не прошли. Просто пришла мода на другие извращения. IMHO И количество этих извращений значительно увеличилось. NC>Энтузиастам и "вольным художникам" не место в индустрии.
Место. И притом денежное место. Индустрия большая. Даже в замой замшелой конторе с шизофреническими процессами разработки, есть место творчеству. Просто у архитектора — одно поле для творчества, у программиста — другое. У меня есть друзья, я по одному взгляду могу сказать кто какой код писал. Потому как каждый индивидуален в своих предпочтениях. NC>Все вышенаписанное — мое имхо.
И слава богу.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Это уже совсем несерьезно. Человек спрашивал, как технически, т.е. с помощью каких средств языка С++ можно такое сделать. Я ему и показал. Неужели я не понимаю, что 1000 может не хватить ????
Я не знаю чего ты понимаешь, я не телепат. Но я вижу, что ты привел код, который запрещено применять в коммерческом программировании под страхом смертной казни. Мы приводим такой код только в курсе сетевых технологий, как пример заведомо небезопасного подхода.
PD>А, прошу прощения, если не знать или хотя бы предполагать общий размер, то задача вообще не разрешима в однопроходном варианте. Потому как нельзя копировать в буфер, не выделив его предварительно. А длины в С++ не хранятся, в отличие от С#. На Паскале можно, там они хранятся.
И после этого кто-то будет обвинять C# в неэффективности???
Я приводил пример пессимального кода, который на шарпе приводит к квадратичной зависимости от полной длины строки. С точки зрения того алгоритма, два прохода или один — не так важно. Все равно мы имеем O(N). Даже наличие хранимой длины не слишком изменяет ситуацию — если длины фрагментов примерно одинаковы, то их количество тоже пропорционально суммарной длине строки, и мы опять имеем O(N). Меняется только константа перед ней. S>>а попытки задействовать хардкор типа rep scasd ни к чему хорошему не приводят. PD>Стоит ли его использовать или нет — вопрос спорный, а вот почему не приведут — объясни, пожалуйста.
Видел своими глазами пример. Как знаток x86 — ассемблера страшно раскритиковал код, сгенерированный VC 7.1 в релизе для приведенного мной фрагмента. Действительно, его код был красивше. А студийный — тихий ужос. Какие-то лишние джампы, как-то там регистры странно использовались... Увы, когда мы сравнили время — студия победила. Видать, ее оптимизатор лучше знает особенности спаривания команд и устройство конвеера. После этого я еще немножко верю в то, что суперкрутой спец сможет написать более эффективный код вручную. Но, во-первых, для этого ему потребуется что-то типа Intel VTune, а во-вторых, чем эффективнее будет этот код, тем больше риска, что на другой модели процессора он окажется в дупе. А в компиляторе я просто переброшу ключик "Target Processor" и усё. Кстати, джиту еще лучше — ему не надо оптимизировать под "blend".
А наивные попытки улучшить код, основанные на прочитанной 10 лет назад книжке "Справочное руководство по Intel 80386" способны только просадить эффективность.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>Хуже. Она использует __declspec(thread). Иначе, сам подумай, что будет, если ее начнут из разных потоков вызывать GZ>>Для этого достаточно одного потока.
PD>Только при некорректном использовании.
Некорректное использование — это, например, случайный реентер.
void parse_line(line* line);
void parse_text(char* text)
{
int n = 0;
char* line;
for(line=strtok(text,"\n"); line; line=strtok(NULL,"\n"))
{
++n;
printf("line #%d", n);
parse_line(line);
}
}
void parse_line(line* line)
{
int n = 0;
char* word;
for(word=strtok(line," "); word; word=strtok(NULL," "))
++n;
printf(" has %d words\n", n);
}
Всё-таки, что ни говори, а strtok — ублюдочная функция. По двум причинам:
1) у неё есть внутреннее состояние, которое можно сбить
2) типичное приложение — цикл — требует двух различных, но согласованных вызовов:
а это — провокация к технологии copy-paste и различным ошибкам (начиная с очепяток).
Можно же было запомнить pattern вместе с курсором строки — раз уж вообще что-то запоминаем.
убивающее сразу трёх зайцев:
— реентерабельно
— приложения без копипаста
— за попытку раскоцать строковый литерал компилятор надаёт по пальцам (разумеется, это обходится... но уже не так просто и бездарно)
Беда сишной библиотеки — в том, что таких глупостей там хватает. Например, функции работы со временем.
И если компилятор не поддерживает TLS (а это, в общем, геморройное дело) — то многопоточное CRT оказывается не совместимо со стандартом (в котором эти глупости есть). Пример: VxWorks.
Здравствуйте, eao197, Вы писали:
E>Пусть наши заказчики побыстрее увидят, что не выгодно покупать неэффективный (большой, неповоротливый) софт.
Интересно почему когда говорят что большой, сразу ассоциируют с неэффективным. Если у меня камаз возит кирпичи, то это лучше чем жигуленок. Хотя жигуленок меньше топлива жрет. Другое дело когда Белазом пытаются в такси поиграться. Конечно светофоры полегче проезжать, но солярки жрет, немерено.
А ты дать определение, что такое эффективный софт. И что такое неэффективный софт?
С уважением, Gleb.
Здравствуйте, GlebZ, Вы писали:
ie>>Действительно, мы сейчас живем в век дешевой техники и дорогой рабочей силы. Но экономя на поддержке и разработке многие, прежде всего заказчики и начальники, действительно портят программистов. Что однако не умоляет множество глупых и бездарных программ. GZ>Это не заказчики и начальники.
Ну не скажи.... Живой пример. Я попросил своего менеджера ежедневно выделять из моего рабочего времени 1 час на ревью кода вновь пришедшего. Ну не умеет новенький эффективный код писать и это не его вина, не научили еще. Нет же, и так в сроки можем не уложиться. Сдадим этап, тогда если(!) сильно тормозить будет, возможно(!), сделаем ревью... Вот так — если и возможно! А так — работает и пес с ней с эффективностью. Вот кто виноват? Скажи, пожалуйста.
В итоге — пора сдавать, а DataGrid ну уж очень тупит при отрисовке. Студент делал его раскрасску. Хочешь расскажу какой он код в DataGridColumnStyle.Paint напихал
ie>>Вот с архитектором в проекте очень даже повезло. Сейчас используется 5 ЯП с соответсвующими им технологиями. Я бы еще пол года назад сказал бы — да зачем мне какой-то там Питон, .NET форева. (Надеюсь больше меня эти мысли посещать не будут.) Все от начала до конца можно было сделать на .NET. Однако, прилили и C++, и Питон, и Ява Скритп, и Перл. Чего добились — думали: путаницы и неразберихи — оказалось: простоты и эффективноти! GZ>А вот это плохо. Смешивать питон с перлом.
Смотря что понимать под "смешивать". Если я не ошибаюсь Перл пришел из-за необходимости генерить Excel отчеты (могу ошибаться, сам в Перловую часть не разу не лазил). Ну нет в .NET средств эффективной генерации Excel отчетов. В Perl есть, взяли, прикрутили. Почему это плохо? Лично мне, да никому другому, не надо переключаться между всеми 5ю языками. Мне пока приходилось работать над ++ модулями и .NET. Понадобится лезть куда-то еще — есть проектная документация. Так что. А к Питону Перл никак не завязан.
GZ>Будь моя воля, я бы привел все к одному языку.
И я сначала тоже так хотел...
GZ>Очень трудно переключаться с одного языка на другой. Вроде бы очень похоже, и термины такие-же. Только дизайн программ весьма зависит от используемого языка. Есть языки которые от которых зависят выбранные технологии. Тут хочешь не хочешь надо. И это хорошо. Но если что-то можно сделать одним языком, то это нужно делать именно этим языком.
Ну вот тот же пример с тестом Павла. Он явно дает понять, что ++ код эффективней справляется с поставленной задачей. Так и сделать эту чать на ++, конечно, без фанатизма, если эта часть действительно критичная, а не бегать каждый раз делать на ++ все что там даст выйгрыш в скорости и использовании памяти.
GZ>С чего все началось. Началось с того, что к Net программам Павел начал приставлять свойства C++. Ну нет у него многих свойств С++. Точно также и нет многих свойств C# у С++. В результате, дизайн программ существенно различается. По форуму Net очень часто поступают вопросы, сквозь которого проступает C++. GZ>И данный пост Павла(которым он наконец разродился) именно связан с темой сравнения с С++.
Да, и это не может не огорчать. Вместо того чтоб спорить что же все таки лучше, общими усилиями написали бы статью, о том какие классы задач и их подзадач с помощью какой технологии эффективно решаются.
Здравствуйте, Дарней, Вы писали:
Д>Научить обычного, не озабоченного "оптимизацией-везде-где-можно" программиста оптимизировать программы куда проще, чем научить "байтовыжимателя" писать нормальный и понятный код. Потому что второй всегда будет искать, как в .NET обнулить поля структуры с помощью ZeroMemory (да-да, это намек ) — вместо того, чтобы проектировать архитектуру. Да еще и считать окружающих идиотами, потому что они не понимают, как же это важно — обязательно залезть на нижний уровень по самый локоть.
Не согласен. Я бы сказал, что это вещи вещи независимые — "этого научить проще тому-то, чем вот этого — противоположному". Здесь главное — чтобы человек обладал некими общими инженерными навыками. Фишка в том, что если человек умеет оперировать байтами в памяти, он как минимум знает, как устроен компьютер. И если он является инженером по своей сущности, то он очень быстро поймет, почему этого не надо делать в дот-нет. И наоборот, если человек начал с дот-нет, но при этом он обладает некими инженерными знаниями, он очень быстро разберется в том, как надо делать эффективно. Встречаются упертые личности — одни на ASM, другие — на C#, но они — не инженеры. И вопрос переучивания — он больше психологический чем технический. Если человек является инженером по своей психологии, то он переучивается легко — хоть туда, хоть сюда. Если же это для него туго, то наилучший способ его задействовать — это поставить на ковейер — пусть работает как машина Тьюринга и выполняет команды. Не хочет? — ну и ладно, найдем другого. Все это и ко мне тоже относится — так что просьба не принимать на личный счет.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, GlebZ, Вы писали:
GZ>Да уж. Я тогда маленький был. Слышал о монстрах которые для того чтобы понять программу переписывали с ассемблера на коды.
Нет. Они просто ее писали в кодах, с самого начала
>Таже NT4 — с последними сервис паками мег 100 занимает оперативы.
У нас еще старый класс есть, для первокурсников, там 64 Мб и NT4. Вполне работает, SP последний.
GZ>Я бы не стал так говорить. Можно просто программы классифицировать: GZ>1. Резидентные программы на машинах пользователей. Они действительно должны быть компактными, не должны забирать много ресурсов компа, и не мешать пользователю выполнять его основную работу.
+
GZ>2. Резидентные серверные программы. Строго наоборот. Они должны адаптировать полностью ресурсы компьютера ради своей эффективности. И никак иначе.
+-. И да, и нет. Потму как этих серверных программ на машине может быть несколько, и лучше бы им не брать все ресурсы компьютера, а то придется по серверу на каждую программу иметь.
GZ>3. Пользовательские программы. Наверно этот класс программ ты и имел ввиду. Вот именно это и есть путь для компромиса. И компромисс между функциональностью и ресурсами. Если функциональность нужная, и она требует достаточно ресурсов, то пользователь не будет возражать, по опыту знаю. Если в требованиях к программе не записано что попутно должны генерится сцены 3D Studio Max, то ему несложно будет выгрузить ее, или понять о том, что это была именно его ошибка. Но вот если функциональность ненужная, а требует достаточно ресурсов, то здесь и я сильно возмущаюсь(а такое на каждом шагу ). Но существует еще вопрос, что значит избыточность ресурсов? Если моя программа занимает на N мегабайт больше, и при этом я уверен что количество ошибок(которые есть будут и полностью их поубивать нельзя) значительно меньше, то я займу эти N мегабайт. В принципе, это и есть некоторая цель Net Framework.
Если я напишу это же без FrameWork, алгоритм будет тот же, эффективность выше и памяти меньше, то это будет лучше. А то, что на FrameWork ошибок будет меньше — не уверен. Не все сводится к мемори ликам и некорректным индексам. От ошибок алгоритма меня никакой FrameWork не защащает. Складывать килограммы с метрами (вместо того, чтобы умножать) и там вполне можно, .
>Пользовательские компьютеры сейчас избыточны. У них значительно больше памяти чем нужно, и процессоры значительно быстрее чем нужно для большинство задач.
Я бы эту фразу перевернул.
Большинство программ таково, что они используют значительно больше памяти и процессорного времени, чем им в действительности нужно. Поэтому программ, которые могли бы при оптимальной эффективности использовать память и процессор, не существует (почти), так как при нынешнем стиле написания программ им нужны намного большие ресурсы, которых пока нет.
GZ>Все это ресурсы избыточны для повседневной работы. Мне не жалко 20 мегабайт — если у меня их 500.
Во-во. Тебе надо 20, а берешь 40. Мне надо 50 — беру 80. Ему надо 100 — берет 150. А этому надо еще 100 — пошел вон, памяти больше нет.
>Если у меня есть вариант, что адаптировав эту избыточность я повышену эффективность даже не программы. а разработки, я ею воспользуюсь.
Да, увы, это так. Ты сделаешь быстрее, не спорю. И сэкономишь несколько К$ на своей зарплате. А в итоге 100,000 пользователей потратят несколько сотен тысяч $ на память, которую твоя программа заняла и не использует.
GZ>Для данной конкретной задачи, это корректное замечание. Net — не очень подходит под числодробилки.
Да ведь нам говорят, что .Net — генеральная линия развития, а те, кому она не нравится — неандертальцы. Вот и мне сегодня заказчик сообщил, что планирует нечто на .Net. Пока не знаю что. И не убедишь его, что это , м.б. не лучшее решение.
GZ>>>Это взгляд со стороны. Разработчики все понимают. Но понимают и другое. Здесь уже несколько раз обсуждалось. Ошибиться в том, что ты неправильно определил место торможения, потратил много времени и сил на работу которая не нужна, значительно хуже. Поэтому лучше сначало сделать, а потом заниматься выявлением узких мест.
"У нас никогда нет времени на то, чтобы сделать все как следует, но всегда есть время на переделки"
>А также оптимизацией памяти, если ее оказалось недостаточно.
Ничего ты не соптимизиуешь. Не ты лично, а те, кто к эффективности не привык. Им и в голову не придет, что это все на 20 Мб может меньше требовать.
GZ>1. Если ты получил понятную программу, достаточно маленьку по исходным кодам, которую прочитает любой ребенок, и которая представляет вверх искуства программирования на ООП, это совсем не значит что она есть эффективна в плане использования памяти и процессора. Даже сказал бы наоборот. Но вот то, что в ней ошибки локализованы, сопровождать ее легко — это факт. После этого ее доводят до требуемого уровня производительности. Это делается легко, поскольку дизайн программы легко сопровождаем.
Ну и заявление! Дизайн понятен, сопровождение легко, след-но, оптимизировать будет несложно! А то, что для оптимального решения задачи, возможно, надо не в деталях оптимизировать, а все решение пересмотреть и весь дизайн переделать — это ты не допускаешь ? Совсем другим способом ее решать!
GZ>Во — вторых, ты увеличиваешь сложность дизайна тогда когда он наиболее важен. В результате, при добавлении функциональности увеличивается количество ошибок. IMHO Это более тяжко чем неэффективное использование ресурсов.
ИМХО это лечится рано или поздно, а первое — не всегда.
GZ>Вобщем, мое мнение, что оптимизация программ по используемым ресурсам, должны проходить в 3 плоскостях: GZ>1. При построении архитектуры. Мы еще видим все проблемы в комплексе, и наиболее крупные можем сразу решить.
+
GZ>2. Алгоритмическая оптимизация. Неэффективный алгоритм на порядки хуже неоптимизированного кода.
+++
GZ>3. Оптимизация готового продукта под конкретные требования пользователя. Свое мнение я уже описал.
+-
GZ>Пользуйся альтернативами Я понимаю что в случае крупных монополистов — такое плохо проходит. Слишком высока сложность программ. Но нельзя так говорить о всей отрасли. Пользуются же мирандой вместо аськи.
Да, а вместо Net Framework что предложишь ? Вместо MS Office ?
PD>>Если я это сделаю, и все же уложусь в мег, ты меня все равно выгонишь ? Если я вместо буфера в несколько мег, в котроый все читается, использую MMF, в котором доступ будет только к тому, что реально требуется — тоже выгонишь ? GZ>Да. Я вполне представляю весь процесс сооружения такой программы. Если ты потратил время на то, чтобы адаптировать решение на меньшие ресурсы, когда я знаю что ресурсы заказчика(или предполагаемого заказчика) значительно больше, то безусловно. Ты проделал работу, которая никому не нужна. Мало того, ты усложнил сопровождение программы. Для программ класса серверов приложений — я не вижу исключений из этого правила.
Опять -таки — все верно, если у тебя единственный заказчик. Ему хоть на 2Gb пиши, если у него их 4. Но я-то о других случаях говорю.
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Оптимизация всего и вся либо же не использование заведомо неэффективных конструкций — и ты не видишь разницы ? Ну, тогда сложно сказать что-то еще.
Д>А ты прочитал статью? Там есть как раз про "заведомо неэффективные конструкции". Почитай, в частности, про страшный алгоритм сложности f(n^3)
Ну, во-первых, эта статья есть гораздо ближе, да еще и на русском.
А во-вторых, опять же не туда показываешь. Я об общем стиле написания говорю, о заведомо неэффективных конструкциях, которые порой используются. В определенных случаях это может не сказаться, согласен. А вот когда весь код таким образом пишут, то повышается общий уровень неэффективности.
Вот, кстати, дай мне ответ. Хотя это лучше в .net, но ИМХО не страшно и здесь.
Перекодирование строки из файла из 866 в 1251.
Все что я нашел, сводится к
public string MyDecoder(string str)
{
byte[] b = Encoding.GetEncoding(866).GetBytes(str);
str = Encoding.GetEncoding(1251).GetString(b);
return str;
}
или вариациям на эту тему
Имеем здесь
Память
Исходная строка — 2N байт (N- число символов). Если строка из файла, то StreamReader еще поработал, чтобы ее из 866 в юникод перевести. И внутри себя он без массива в N байт не обошелся.
Массив b — N байт
Результирующая строка — 2N байт
Вывод ее в другой файл — еще N байт в 1251 внутри StreamWriter.
Итого 7N байт
А нужно всего-то N байт.
Время
StreamReader в юникод переделывал — цикл
GetBytes — цикл
GetString — цикл
StreamWrite записывает в файл с перекодировкой — цикл.
Итого 4 цикла. А нужен всего 1.
Я вполне допускаю, что ты сейчас мне это эффективнее напишешь. Ты. А все будут именно это и делать.
Здравствуйте, pp2, Вы писали:
pp2>Маленький совет сочуствующим автору. Вы любите чистое творчество, сложные неординарные задачи, непаханные поля новых технологий? Уходите из программирования. Я имею ввиду не "телом", а "душой". Т.е. можно продолжать зарабатывать на этом поле деньги, а тем временем прорабатывать новые, хотя бы смежные, отрасли. Чертовски приятно видеть как происходит становление новой технологии! И там есть где разгуляться пока туда не нагрянули люди с огромными мешками денег и не началась грызня за эти самые мешки
Давайте это Ричарду Столлману (GCC, emacs), Линусу Торвальдсу (Linux), Тео да Радту (OpenBSD), Гвидо ван Россому (Python), Ларри Уоллу (Perl), Якиро Матцумото (Ruby), ...(список можно продолжать)..., раcскажем. А то мужики, право слово, фигней страдают. Надо их жизни-то научить.
Ребята, если вы относитесь к программированию как к обычной работе, средству заработка, то и относитесь себе так и дальше. Зачем же подобные советы давать (вот еще один: Re: Об эффективности программ
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Перекодирование строки из файла из 866 в 1251.
PD>Все что я нашел, сводится к
PD>public string MyDecoder(string str) PD>{ PD> byte[] b = Encoding.GetEncoding(866).GetBytes(str); PD> str = Encoding.GetEncoding(1251).GetString(b); PD> return str; PD>}
PD>или вариациям на эту тему
Код некорректен: строка (string) в .NET состоит из символов юникода и к ней не применимо понятие кодировки, поэтому вышеприведенный код просто напросто коверкает строку, т.к.
byte[] b = Encoding.GetEncoding(866).GetBytes(str); // получили текст из строки в массив байт в кодировке 866
str = Encoding.GetEncoding(1251).GetString(b); // интерпретировали каждый байт из b в кодировке 1251 — в результате в str одни крякозяблы
Фактически, если необходимо записать строку в кодировке 1251 то это делается просто:
byte[] b = Encoding.GetEncoding(1251).GetBytes(str);
Если же надо преобразовать кодировку массива байт, то не надо предварительно преобразовывать массив в строку:
public byte[] MyDecoder( byte[] byte866 )
{
byte[] byte1251 = Encoding.Convert( Encoding.GetEncoding(866), Encoding.GetEncoding(1251), byte866 );
return byte1251;
}
Вероятно проблема не в неэффективности концепции framework .NET, а в понимании используемых технологий
Но, как мне кажется, без понимания основ эффективно писать вообще ни на чем нельзя.
Здравствуйте, eao197, Вы писали:
E>Тенденция на лицо, но это совсем не означает, что ей нужно безусловно поддаваться. Тут, имхо, так: либо ты ищещь оправдания, либо возможности. Возможности искать труднее. Я, например, пытаюсь. И поэтому мне не интересно думать о том, что искусство становится ремеслом, места для фантазии не остается, индустрия выживает изобретателей и пр. Это не конструктивно.
Согласен. Не буду "оправдываться". Исходный мой пост был несколько эмоционален и направлен на поиск этих самых оправданий и описанию тенденций. Действительно, возможности искать стоит, хотя это и не легко. Уйти из программирования — это самый простой способ (хотя иногда именно это радикальное решение помогает отдохнуть и взглянуть на ситуацию со стороны). Можно не уходить а пытаться жить и даже творить что-то в имеющихся условиях. Но исходная дискуссия насколько я понял, шла именно вокруг массового "среднего" программиста. Профессионалы врядли так просто "уйдут" из отрасли, а вот середнячку тяжелее, он может и бросить это дело, если что... Хотя многие профессионалы были замечены в соседних с ИТ областях, значит "изменяют" все-таки иногда
E>Среди заповедей для художника от Сальвадора Дали была такая: "Художник -- рисуй!" E>Очень к месту, имхо.
Ну мы же здесь не только "художники", но и философы! А вообще конечно,
+1
Здравствуйте, Павел Кузнецов, Вы писали:
>> Вообще-то особенно при работе в команде код должен быть подчинен стандарту. Суть в том, что основная часть производства софта это именно индустрия, масс-продакшн.
ПК>Это не так хотя бы по простому факту того, что выпускаемые программы отличаются друг от друга. В противном случае не понимаю, зачем их много...
Диванов тоже много разных. И все произведены серийно.
Здравствуйте, McSeem2, Вы писали:
MS>Это я к тому, по достижении "определенной стадии просветления" (это такой само-сарказм) оказывается, что писать эффективный код — это не только приятно и интересно, но он еще и оказывается гораздо надежнее!
Ну и где он, этот эффективный и надежный код? Пойти что ли, поискать на улицах с фонарем?
MS> И что характерно, индустрия, "в которой не место энтузиастам" проявляет тенденцию к спросу на таких "динозавров".
Ну это известный факт — что хороший программист за одно и то же время сделает как более эффективный, так и более надежный код, чем плохой прогораммист. Ну и что это докажет то? Хороших программистов все равно не хватает.
Здравствуйте, mrozov, Вы писали:
M>То, что вы не призываете заниматься микрооптимизацией — это замечательно. Хотя в свете существования компиляторов, которые оптимизируют ассемблерный код лучше, чем 99% программистов — это не так уж и удивительно .Однако из ваших постов можно сделать вывод, что вы отказываете в праве на существование (доминирование?) таким системам, как Java или .net, именно на основе их неоптимальности. И в моих (например) глазах такие тезисы абсолютно равнозначны призывам массово использовать asm для построения UI.
Нет. Я просто удивляюсь, что эти ситсемы используют алгоритмы, в которых вместо одного прохода требуется 3, вместо одного блока памяти — 2 и т.д. И мне говорят, что при этом повышается читабельность и легче сопровождение и т.д. Вот это я не понимаю и не принимаю.
M>Излишней является любая оптимизация, которая не направлена на изменение ситуации, при которой система не способна уложиться в определенные в проекте временные рамки на том оборудовании, для работы на котором она предназначена.
Определение ИМХО некорректно, и я об этом уже писал. Если речь идет о программе для одного заказчика, то бога ради, с ним и решайте, чего ему надо. Когда же речь идет о программах, используемых массово, то излишние затраты ресурсов неоправданы, поскольку есть просто бессмысленная их трата.
M>Не больше. не меньше. Иными словами — для любого ПО можно (нужно?) определить минимально допустимую конфигурацию (критерии могут быть разными) и необходимые показатели быстродействия (в основном — время отклика).
Ну и определи, пожалуйста, на примере ICQ. Первая ее версия, с которой я столкнулся, работала у меня под Windows 95 на машине с 8 Мб памяти. А сейчас ей одной надо 20.
>И любая система, укладывающаяся в эти рамки, является достаточно оптимальной, вне зависимости от того, насколько еще можно ускорить ее работу.
Да укладывается эта ICQ в память современных машин, укладывается вполне. Еще 4-5 таких клиентов — и больше на машине в 256 Мб памяти не останется.
M>По-моему, это клинический факт. Спорить можно только с тем, насколько вольно постановщик задачи обращается с этими самыми критериями достаточности.
А не мог бы кто-то определить для этой ICQ , кто здесь постановщик задачи, и насколько вольно он обращается с этими самыми критериями ? . Что-то мне кажется, что они сами тут определили и обращаются.
Здравствуйте, McSeem2, Вы писали:
MS>по достижении "определенной стадии просветления" (это такой само-сарказм) оказывается, что писать эффективный код — это не только приятно и интересно, но он еще и оказывается гораздо надежнее!
Когда-то спросил старого программера, как писать оптимальные программы. Я то думал, вопрос с подковыркой (оптимизировать по скорости или по размеру можно). А он ответил просто: "упрощай их".
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
Здравствуйте, mrozov, Вы писали:
M>Здравствуйте, Павел Кузнецов, Вы писали:
ПК>>Если у программиста проблемы с ДНК, то лечится это не инструментальными средствами. Инструменты, напротив, должны давать возможности тем программистам, у которых с ДНК все в порядке.
M>А вот это — более чем спорно. Я бы даже сказал, что подобные заявления отдают манией величия =) M>Не думаю, что стоит вот так категорично говорить о том, что вам должны инструментальные средства.
Я поддерживаю Великое ИМХО Кузнецова Павла.
Вилка — инструмент, ей можно красиво есь не теря собственного достоинства, есть фруктовая вилка, ей можно есть фрукты. Это вводная.
Так вот во Франции гдн-то в средние века проверяли жениха ( в приличных домах дворянского сословия ), претенденту подавали спелый персик, который он должен был съесть именно фруктовой вилкой и ножом, не теряя собственного достоинства, и непринужденно ведя светскую беседу с будующими родственниками. В тоже время мастеровые ели руками.
Продолжить аналогию про вилки:
Если фруктовую вилку всадить себе в глаз то можно не только лишиться глаза, но и умереть чтобы этого не случилось, — можно на вилку надеть винную пробку, но тогда, имея соответсвующие навыки — нельзя съесть персик.
Здравствуйте, mrozov, Вы писали:
M>О! Именно об этом я и говорю. А так как "взрослых" программистов — ничтожное меньшинство, то мы и приходим к неутешительному выводу по поводу того, кому и что именно должны инструментальные средства.
Резюмируем:
Вы писали:
Заметка из жизни. Если у программиста проблемы с ДНК, то C# многое прощает, а вот шаблоны в С++ многое усугубляют.
То что я написал — Вы не опровергли, а вместо этого согласились.
Соответсвенно вывод:
Разработчики инструментальных средств — считают так как Я и Павел Кузнецов ( Это ИМХО ), а не так как Вы .
Если на секундочку вернуться к фривольному тону, то:
ИНструсентальные средства — это теже дети, они растут, взрослеют, и им становяться неинтересны детские наборы посуды, они подражают взрослым, они хотят, как взрослые, есть персики вилкой, и при этом — чувчтвовать себе непринужденно.
Как пример из многострадального Шарпа (я могу ошибаться так как сам на нем не пищу) вроде как в 2.0 char* стал safe дабы вызовы WIN API быдли safe — ребенка потянуло к взрослым игрушкам ???
M> Поздравляю!
Здравствуйте, GlebZ, Вы писали:
GZ>Создается, но она не мусор. Строка в Net — immutable. Строка не может быть изменена, можно создавать только новые. Row возьмет ссылку на строку и будет оперировать именно им. Он спокойно может сохранять у себя ссылку на строку, передавать ее другим, не боясь что кто-то изменит ее.
Это все верно, но тут ты играешь на том, что эти подстроки нужны и дальше (в данном случае будут использованы в rows). А вот когда они дальше как таковые не нужны (т.е нигде храниться не будут) — тут-то ты и проиграешь.
p=strtok(myString,",");
while(p)
{
printf("%d\n",p);
p = strtok(NULL,",")
}
Здесь эти временные подстроки никому не нужны после печати. Если ты это перепишешь на С#, то получится
int i, l=0;
while ((i=myString.IndexOf(",", l))!=-1)
{
Console.WriteLine(myString.Substring(i, l-i);
l=i;
}
В итоге для того, чтобы распечатать подстроки, ты создал их, напечатал, и, конечно, они стали добычей GC. А я их не создавал. Правда, строку испортил, но это уж так strtok сделана. Могу свою функцию написать, которая то же сделает, но строку портить не будет.
Если считешь мой пример искусственным — хорошо, пусть в задаче требуется разбить на слова, а потом каждое слово проверить каким-то образом. Я опять-таки подстроки делать не буду, а ты будешь.
Прочитал я то. что написали участники дискуссии. В общем, со многим можно согласиться. С тезисом "клиент всегда прав" не поспоришь. Да и тот факт, что нынешнее программирование — это работа за деньги, а кто платит, тот и заказывает музыку, тоже вне сомнения. Хотя средства разраюотки — прерогатива не только заказчика, но и разработчика.
Но вот утверждение, что, дескать в этом и заключается новая ситуация в IT-индустрии — ИМХО спорно. Боюсь, что она не новая, а очень даже старая.
Есть такой класс программистов — программисты на Visual Basic. VB как-то в России не слишком популярен ИМХО и признаваться, что на нем пишешь, даже как-то стыдно считалось . А вот в мире он весьма популярен, где-то мне встретилось утверждение, что в мире около 1 млн. программистов на VB. За то. что мне память здесь не изменяет — не поручусь, так что критиковать это утверждение не надо. И потом, неизвестно кого они туда включили — может, школьников средних школ тоже
Так вот, эти самые программисты на VB свою работу делали, а вот эффективности от них никто и не ждал. Потому что программы для массового использования они не делали, а делали для данного конкретного случая, порой для себя, или для заказчика, которому она нужна, а торговать он ей вовсе не собирается. Кстати, если во времена своих химических расчетов имел бы PC с VB — вполне возможно, на нем бы и начал свою карьеру. Просто, удобно, легко...
Что касается эффективности — кто ее от Бейсика когда ждал ? К нему традиционное отношение как к чему-то неэффективному — интерпретатор же! И пусть VB никакой не интерпретатор — от однажды завоеванной репутации так легко не отделаешься
Так вот, у меня впечатление такое, что этот стиль VB попросту начинает проникать в те области, куда программистов VB раньше и на пушечный выстрел не подпускали, да они и сами не стремились, так как знали, что им там делать нечего — не влезут они с VB в имеющиеся ресурсы, не добьются нужной производительности. А ресурсы увеличились — и они пошли!
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Это не так хотя бы по простому факту того, что выпускаемые программы отличаются друг от друга. В противном случае не понимаю, зачем их много...
Неверная аналогия (тут рядом это уже обсуждалось). Разработка программы это не изготовление конкретного дивана, а проектирование конкретной модели дивана.
Д>Как я уже говорил, ведущие собаководы говорят — "читаемость и легкость расширения кода стоят превыше всего, в том числе и оптимальности по объему/производительности/любой иной"
По второму кругу пойдем. Ведущие автомобилестроители говорят. что удобства разборки и сборки автомобиля важнее его характерстик.
Д>отвечу заранее — нет, я не согласен с тем, что более простой код будет и более оптимальным. Совпадение одного с другим вполне возможно, но в большинстве случаев это вещи взаимоисключающие.
И да, и нет... В большинстве — не согласен, а бывать — конечно, бывает.
PD>>Программа делается для России. Приведи ситуацию, в которой здесь возможен buffer overrun. Фамилию и имя, please , в студию.
Д>фамилия очень простая — "Ивановвввввввввввввввввввввввввввввввв" (повторить нужное количество раз). Просто оператор заснул на клаве. Ах, такого не бывает, говоришь?
Нет, не бывает. Потому как в моей задаче данные брались из SQL сервера, там попросту не могло быть такого — места нет.
Д>Я уж не говорю о том, что это решение не только опасно, но еще и очень далеко от оптимума по производительности, которого тебе так сильно хотелось. Не догадываешься, почему? Рекомендую немного помедитировать над текстом sprintf
А не надо медитировать. Я sprintf просто для примера привел. Реально у меня была ConcatenateStrings собственной разработки. Черт ее. sprintf, знает, как она там по форматам преобразует
Д>как я уже говорил, твой пример к рассматриваемой ситуации с sprintf не имеет ни малейшего отношения. Поэтому смотреть тут особо и не на что.
Ну не на что так не на что.
Д>разница в том, что ошибку переполнения можно обработать программно, ибо к порче сторонних данных она не ведет. Потертый стек — это однозначно полный трындец программе.
Ну и ставь себе try-catch на каждый оператор. Не много их найдется, которые в принципе не могли бы ошибку сгенерировать.
Д>Эти самые "общепринятые принципы" были изучены мной на своей собственной шкуре, и на немаленьком количестве набитых шишек. Именно поэтому я говорю, что если ты вдруг подумал, что нужно нарушить один из них, потому что "это нужно для решения задачи и другого выхода нет" — значит, садись и думай еще раз.
Да зачем мне об этом опять думать ? Проект этот я давно сдал, он и сейчас там работает, и будет еще бог знает сколько времени работать, и жалоб не было, хотя обработаны миллионы, если не десятки миллионов образцов, так что уж давно бы баг проявился бы
Д>Я в свое время тоже увлекался написанием мега-оптимизированных программ. Написал например для эксперимента дизассемблер для Z80, который целиком помещался в 1.5 килобайта. Но с тех пор я набил немало шишек, стал несколько мудрее и перестал заниматься подобной ерундой.
Ну и на здоровье. Я все равно придерживаюсь той точки зрения, что лучше сделать с нарушением правил, чем по правилам ничего не сделать.
Вот ответь прямо на вопрос. Тебе предлагается проект. К нему жесткие требования по времени работы, не уложишься — не примут. Написать со всеми твоими проверками — знаешь сам, что не уложишься. Но знаешь и, что если займешься "написанием мега-оптимизированных программ" — уложишься. Ядерным реактором это не управляет, самолеты не водит, крах если раз в месяц произойдет — не смертельно, перезапустят. Твои действия ?
PD>>В конце концов лучше написать работающую программу не по правилам, чем по правилам ничего не сделать.
Д>А еще лучше — написать работающую программу, которая не будет использовать никаких грязных хаков. См также пример по sprintf выше
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, alexeiz, Вы писали:
A>>Так не пойдет. Чтобы было эквивалентно С++ варианту нужно ещё из StringBuilder получить String. GZ>Почему?
В C++ версии на входе две строки на выходе одна. В C# — на выходе какой-то буфер (StringBuilder то есть). Чтобы его использовать как строку, нужно еще совершить преобразование.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, srggal, Вы писали:
S>>Здравствуйте, Pavel Dvorkin, Вы писали:
S>>Хоть Вы и читтер уважаемый, ан все равно приятно увидеть Думмера, ( поглаживая свой БФЖ ), и вспоминать как БФЖ рулит на 7мом уровне в дедматч. Эххх.
PD>Ради бога, переведи на русский, а то я даже не знаю, как на все это реагировать .
PD>P.S. Код, который ты цитируешь — не мой, см.
Уппс, ошибочка вышла.... Еще одна проблема с копипастом
Выделенные строки это читкоды легендарного дума, если не ошибаюсь:
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Pavel Dvorkin, Вы писали:
WH> StringBuilder sb = new StringBuilder(); WH>... WH> for (int i = 0; i < 100000; ++i) WH> { WH> sb.Length = 0; WH> sb.Append(szFirstName); WH> sb.Append(szLastName); WH> } WH>[/c#] WH>0,04493758
WH>Оптимизированый вариант на C# получается на уровне С++ Ну чуть медленнее.
Проверять не буду, приму на веру. Все верно, я так и ожидал. Только одно имей в виду — StringBuilder постоянно хранит и изменяет поле длины. И это не бесплатно. Ты уже заплатил за вычисление этой длины вот здесь
(именно здесь, может, и нет, так как строки константые, но в других случаях — да)
Естественно, когда мы миллион раз одни и те же строки сцепляем, это не надо миллилн раз делать. А вот если строки все время разные, то вычисление их длины входит в плату за конкатенацию.
WH>Кстати для корректности теста перепиши свои на wchar_t.
А зачем ? Надо будет — перепишу. А пока мне и так хорошо — там, как я знаю, только 0-127. И незачем мне делать 50% оверхед. Я могу и не переписывать. А вот ты можешь на ASCII переписать ?
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, alexeiz, Вы писали:
A>>Приемущество языка С заключается в том, что он позволяет (не требует а позволяет) спуститься на уровень железа. Для С# это очень и очень ограничено. Все размышления о выходе за границы массива идут лесом. Это просто отдельный разговор. GZ>Закон относительности. Можно повернуть и по другому. Преимущества C# то, что он не позволяет делать ошибки выхода за границы массива. Хотя и это неправда. Я прямо написал, что можно так делать, но это особый случай называемый unsafe кодом. Так что и C# умеет работать с памятью и указателями. Так что преимущества здесь нет.
Я посмотрю, как ты будешь со строками в unsafe коде работать. То, что ты можешь работать с памятью и указателями, для строк не имеет ни малейшего значения.
Здравствуйте, srggal, Вы писали:
S>Ламмеров — отучил бы, а я — выходил бы на круг по которому Вы бегаете с пистолетом, и не сделав бы ни одного выстрела смотрел бы как тело врага, возможно Ваше, оседает на пол
Ну, то что ты трепачь я уже давно понял.
S>БФГ в Думе2 — надо уметь пользоваться, не нужно стрелять им в голову, выстрел в стену и стрейф без иззменения угла, после выстрела — и все что видит владелец БФЖ, пока кипит на стене выстрел ( в том числе и за стеной ), — все умирает.
Переставай дружить с Маней Величко. Это плохая подруга.
Вместо этого лучше представляй себе что разговаривашь с людми опыт которых как минимум не меньше твоего.
S>Но это так азы... Просто ностальгией повеяло
Это безграмотное обяснение. Реальное обяснение намного сложнее.
Стрэйфить никуда не нужно. Просто при попадании снаряда ВБГ в стену или оппонента проводился мысленный веер состоящий из 43 (за точное число не ручаю) "лучей смерти". Центр веера проводися от туловища стрелвшего по напавлениб к месту поподания. По этому совершенно все равно куда ты смотришь или как ты сртэйфишся. Можно было отвернусться и ждать пока все перадохнут. Вот только с удалением лучи расходятся и наносят все меньше и меньше урона. Да и в узком месте пучок не столь широк чтобы можно было безнаказанно убивать все на своем пути. 100%-ная смерь наступала только при прямом попадании или на небольшом растоянии и малом угле. Плюс к тому огромный лаг при выстреле и характерный звук. Собствнно это позволяло очень многих любителей семерки класть банальным ружьем. Главное было вовремя зайти к ним за спину.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
Д>какая разница — одна и та же, или разные? Длина строки просто вычисляется где-то в другом месте (точнее — в коде, который читает данные из базы. но это уже детали)
Код, который читает данные из базы, длину не вычисляет. Нет такого в SQL SELECT, к примеру. Внутри себя этот SELECT на сервере я не знаю что делает, но мне на клиент в итоге строка попадает как последовательность ASCIIZ. Последовательность ASCIIZ — "сырые" данные, откуда они взялись — не важно. А в объекте string на входе конструктора эти же сырые данные (а как ты еще string сконструируешь, если не по ASCIIZ или по другому string ?), а вот в полученном объекте — уже с длиной. Т.е. длину при создании экземпляра string вычислили.
Давай простой пример, искусственный, конечно. Есть огромный файл (1GB , в нем одна текстовая строка, в конце ее , конечно, 0D0A . Я открываю этот файл, делаю на него MMF, позиционируюсь в конец файла, заменяю 0D на 0, имею таким образом строку ASCIIZ. Обрати внимание — файл я не читал. Все — у меня char* pString готов.
А теперь то же самое, но сооруди мне string из данных этого файла. И ты обязан будешь файл прочитать.
Д>Конкатенация ASCIIZ строк неэффективна в принципе, вот что я пытаюсь до тебя довести.
Да ведь во входном мире ничего другого нет. Есть некий входной массив байт (из файла, из сети, ...). Этот набор нам дают и все. И чем-то заканчивают, чтобы знали, когда остановиться.
gets банальный, например. А дальше уж наше дело — то ли string из него соорудить, длину мимоходом посчитав и время потратив, то ли не считать длину, отложить до того момента, когда понадобится (может, и не понадобится) . Кстати, в моем примере с конкатенацией я эту длину мог мимоходом вычислить.
>Читал историю про маляра Шлемиэля?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Как он хранит — не мое дело. А вот возвращает он из без длины.
возвращает не он. Возвращает библиотека доступа к нему, причем — тот конкретный экземпляр, который ты используешь.
PD>Бог с тобой, зачем же ? Ты вообще с MMF знаком ? Там прямой доступ. Если уж мне надо расширить файл, то я просто создам мэппинг на размер, больший, чем текущий размер файла на требуемую величину.
то есть, в данном случае размер хранится где-то отдельно. Иными словами, это не ASCIIZ строка
ноль ты конечно можешь добавить в конец, но в данном случае это будет из разряда "не пришей кобыле хвост"
PD>Да в общем-то ничего интересного. По крайней мере ничего нового для себя я не нашел. Довольно наивные рассуждения, особенно забавно вот это
>>Строка не может содержать нулевые байты. Так что хранить произвольные двоичные данные вроде картинки в формате JPEG в строке нельзя.
PD>Между прочим, JPEG очень неудобно хранить так же в виде стека, линейного списка, двоичного дерева и т.д. И не надо — не предназначены эти структуры для хранения JPEG . Как и строка. Кстати, ты готов хранить JPEG в виде string ?
Я буду хранить в том, что будет удобно для моей задачи. Хоть в массиве, хоть в строке, хоть в дереве.
Забавно, что ты обратил внимание только на это.
Я даже не могу сказать, что ты не видишь леса из-за деревьев. Потому что ты настолько погрузился в разглядывание травы под своими ногами, что даже про существование деревьев забыл.
Здравствуйте, gear nuke, Вы писали:
GN>Думаю для определённых (узких) классов задач решения будут постепенно возникать. Я бы и сам с радостью купил писюк, который весь (кроме монитора) находится в клавиатуре .
Давно забытое старое? (синклер, микроша, вектор, поиск)
Да и сейчас есть тот же mac-mini
PD>Почитайте весь тред, не пожалеете.
Ну читал и дальше что?
1)У меня решарпер кушает на много меньше памяти на проекте который побольше будет.
2)Если ты думаешь что будь решарпер написанан на С++ он бы жрал меньше ресурсов то ты заблуждаешься. Ибо он память не просто так жрет.
3)Плюсы которые дает решарпер значительно перевешивают его прожорливость.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, AndrewVK, Вы писали:
PD>>Почитайте весь тред, не пожалеете.
AVK>Если бы весь софт был на уровне Решарпера, у нас бы было значительно меньше проблем.
Ага. Как-нибудь я соберусь и выскажу всё что о нём думаю
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Все, извини, но это письмо будет точно последним. Времени больше на эти дискуссии нет — увы, заказчик прислал наконец спецификации проекта, и он именно на С# .
Заказчик всегда прав!
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
E>Тут уже кто-то сказал, что это "потом" никогда не наступает.
Это "потом" наступить может лишь тогда, когда этого потребует заказчик, сиречь заплатит еще денег.(Естественно, если в первоначальных требованиях этого не было).
В свободных же проектах это "потом" может наступить в зависимости от энтузиазма разработчиков, и, имхо, главное, от наличия у них времени, так что не надо приводить в пример некоммерческие проекты в данном случае.
Здравствуйте, Pavel Dvorkin, Вы писали:
GN>>Когда-то спросил старого программера, как писать оптимальные программы. Я то думал, вопрос с подковыркой (оптимизировать по скорости или по размеру можно). А он ответил просто: "упрощай их".
PD>Хотел я в исходном постинге напомнить про один принцип. Потом решил, что введет ненужную игривость
PD>KISS — Keep It Simple, Stupid!
gear nuke wrote: > GZ>Мне не интересен сам вопрос про кэш. Кэш неуправляем и эвристичен. Я > предполагаю более управляемую архитектуру. > > По сути, Вы предлагаете управляемый кэш. Это способно дать выигрыш. И > сущесвующие методики работы с кэшем тоже дают выигрыш. Вопрос в том, > *почему* до сих пор нет ни одного компилятора использующего это эффективно?
Современное управление кешем неполно (у кеша всегда есть и своё мнение
кроме prefetchnta) и непереносимо, поэтому никто не заморачивается?
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>1.Не сотвори себе кумира!
Д>мы ведь говорили про принцип KISS? вот у меня есть предположение, что люди, которые стояли у истоков Юникс, знают намного больше нас с тобой о его точном значении
Не понял. Или ты имеешь в виду, что я неправильно расшифровал аббревиатуру ?
Д>мы ведь говорим о программах, а не о машинах? Д>а вот как раз они глохнут. и "взрываются". причем регулярно
Не без этого, не спорю. Но бороться за то, чтобы этого не было, надо с соразмерными затратами. Если, конечно, речь не идет о программе управления ядерным реактором. Если ICQ раз в месяц падает, то еще вопрос — нужна ли мне ICQ, которая падает раз в 3 месяца и жрет памяти в 3 раза больше.
Д>поэтому давайте сделаем сначала то, что будет нормально ездить и возить грузы. Пусть и не очень быстро, зато с гарантированной доставкой из точки А в точку Б. Причем в целом и непритронутом виде.
Нет, не пойдет. Потому что если с меня за эту поездку на самоновейшем самолете возьмут из Омска в Москву $1000, я предпочту обычный российский поезд, который довезет меня за $100, хотя, возможно, слегка опоздает. Кстати, и риск аварии там не больше, чем у самоновейшего самолета.
А программ без ошибок — не бывает. Вспомни
"Программа, свободная от ошибок, есть абстрактное теоретическое понятие".
Д>многие так думали. пока жареный петух в одно место не клюнул
Ну несерьезно это. Есть страна, для которой я это делал. Есть у них в стране некая информация (извини, но деталей рассказывать не буду). Эта информация там появилпась, когда еще никаких компьютеров на свете не было, а может, и автомобилей не было. И вот я эту информацию в некий буфер заношу. И то, что она никак не может быть больше, чем 500 символов — гарантия в 101%. Никогда не может, ну так же, как имя русское не может быть длиной в 500 символов. А времени считать эту длину абсолютно нет, потому как на все про все мне дано 100 мсек. И в этих условиях ты все же будешь утверждать, что buffer overrun возможен ?
Д>разница в том, что этот код не вызовет порчу стека. а sprintf — вызовет Д>улавливаешь разницу?
Нет, не улавливаю. все равно это кончится неверным поведением программы и в конце концов крахом. Причем скорее всего не здесь, а где-то еще. Так что разницы я не улавливаю. Или ты хочешь сказать, что buffer overrun — это намного хуже, чем integer overflow ? По мне, один черт — все равно дальше ничего хорошего не будет.
На тебе, пожалуйста
int nScreenArea = nScreenWidth * nScreenHeight;
int nSquareLength = sqrt(nScreenArea); // а какого бы размера был квадратный дисплей с таким же числом пикселей ?
и получи sqrt domain error (не помню, как он сейчас называется правильно) — корень из отрицательного числа.
Д>кстати говоря, во многих серьезных конторах за использование любой функции из семейства printf нещадно бьют по рукам. И даже более серьезно — по кошельку.
А это от ситуации зависит. В том проекте, в котором я участвовал, мне все было разрешено, кроме одного — низкой скорости работы. Занял бы на диске лишний Гбайт — простили бы. ОП использовал бы в 2 раза больше, чем надо — тоже простили бы. А вот уложиться я должен был в 100 мсек. Кровь из носу. Потому что если 200 мсек займет — это кончится просто тем, что данный образец будет снят с обработки по нехватке времени, а тем самым число необработанных образцов увеличится. А обрабатывается таких образцов в день примерно 30,000 только на одной машине, и на каждый образец дается не более 3 сек. И за это время к моему ПО делается 10-15 запросов плюс, естественно, то время, которое нужно на оставшуюся часть, а оно есть примерно 60% общего времени. А машин примерно 1000. Борьба шла за каждый процент. И мне все прощалось, только бы быстрее. И сделал я им вместо 100 мсек 20-30 мсек, и были они в полном восторге
А лишних Гбайтов я , кстати, не использовал. И лишней ОП — тоже. Ну разве что самую малость — буфер там был один с запасом в 64 Кбайта
Здравствуйте, IT, Вы писали:
IT>Алгоритмы тут не причём. Упрощать нужно не их самих, а их реализацию.
Опять неверный совет. Что значит упрощать реализацию? Более длинная и запутанная реализация может оказаться эффективнее в виду того, что запутанность — это оптимизации.
Так что урощать нужно грамотным абстрагированием. Любой код можно сдалать понятнее если выразить его через более высокоуровневые абстракции. Возможно при этом он станет и короче, но это уже дело десятое.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Voblin, Вы писали:
V>Здравствуйте, ZevS, Вы писали:
ZS>>- туфли на неснашиваемой подошве (казалось бы — чего проще пустить туда резину как в авто-покрышках)
V>Один мой знакомый делает обувь "Lifetime warranty". Когда я узнал об этом ( => о том, что такое бывает), у меня был шок.
"Мне предложили вечную иглу для примуса, а я не купил. Мне не нужна вечная игла, я не собираюсь жить вечно"
Здравствуйте, gear nuke, Вы писали:
GN>А когда начнут интегрировать RAM в корпус CPU (что бы избавиться от проблем с печатными платами), то как будем добавлять память?
А надо? Для каждого периода времени есть некие негласные принятые объемы памяти. Ввести три градации:
1. Лоэнд — сейчас где-то 128 метров.
2. Лоэнд+ — 256 на сегодня.
3. Мидлэнд — 512.
4. Хайэнд — 1 Гиг.
5. Мечта идиота 4 Гб.
Если это будет статическая память (попросу кэш), то ее можно тактировать частотой ядра и получать офигительные решения. Каждый класс к тому же будет иметь разное число ядер, разную тактовую частоу и т.п.
На будющее просто выростут объемы памяти и частоты. Классы же останутся.
Это кстати позволит делать девайсы миниатюрнее.
Можно пойти и таким путем. делать матери сразу под много процессоров с доставляемыми процессорными блоками. Каждый блок доставляет не только процессор но и память.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Собрался наконец написать. Минусов мне за эти тезисы поставят, это уж точно.
Не видать что-то минусов... Зачем же так сразу пессимистически начинать?
PD> Когда компьютеры были большими, память у них была маленькой и PD>быстродействие тоже. И поэтому гуру от этих ЭВМ ничего, кроме ассемблера PD>(автокода, по-тогдашнему) и не признавали.
Давайте условно расставим факты между "тем" и текущим временем.
Что было раньше:
— программирование не было массовым, там работали Профессионалы, но из другой специальности, собственно такой профессии как программист и не существовало
— компьютеры были "хилые", поэтому просто приходилось писать программы компактно и оптимально, по другому они просто были не работали
— сроки разработки программ были большие, соответственно разрабатывались они тщательнее и больше времени уделялось оптимизации (конкуренция и борьба за рынок не были так выражены)
— в ИТ-сфере крутились не очень большие деньги, отрасль только становилась на ноги
— такие свойства как сопровождаемость и архитектура у программ были постоянно совершенствовались до определенного момента (времени этому уделялось больше, да и работали профессионалы, т.е. средний уровень был высокий)
Что имеем сейчас:
— компьютеры стали мощные
— сроки разработки программ заметно сократились, а сложность их возросла (возросла за счет подключения расчетов из смежных отраслей, которые "увидели" в ИТ отдушину)
— программирование стало массовым, туда потянулись "простые смертные", общий средний уровень квалификации упал (чего стоят нынешние индусы)
— в ИТ-сферу пришли большие деньги и правила бизнеса, и оттуда ушли творчество, остатки наук и искусство, теперь деньги определяют многое, хотя и не все
— появились мыльные пузыри — это следствие больших денег (дотком 2001, например), возникла куча смежных с ИТ мелких бизнесов кормящихся с него и заинтересованных с раздувании этих пузырей в дальнейшем, началась рыночная грызня: нечестные игры с пользователями, скупка конкурентов, монополизация и пр.
— качество программ упало, это очевидно, с другой стороны количество программ возросло (в природе не бывает бесплатного сыра — если вы пишите быстрее, сложнее и больше — качество будет плохим, это закон)
— массовый софт да и хард стал вопиюще несопровождаемым и "кривым" архитектурно — это просто следствие всех вышеперечисленных пунктов да еще и поддержка совместимости сказывается, тем не менее большое внимание сейчас уделяют исправлению архитектуры (новые языки, массовые правила, паттерны банды 4-х и т.п.)
— программирование стало занудной рутиной во многих своих проявлениях
Так что криминала не вижу. Так все отрасли развиваются и ИТ — не исключение. Отсутствие "эффективных" программ сейчас вполне объяснимо и терпимо. Так просто надо сейчас и все.
Кстати, заметили ли вы что большинство фундаментальных открытий в ИТ отрасли было сделано в 60-80-е годы? Нет, сейчас тоже что-то открывают, но это эволюционные открытия, а не революционные. Например из-за возросшего быстродействия теперь стало возможным использовать те более эффективные алгоритмы, которые раньше считались слабо перспективными и т.п. И самые "новые" процессоры, шины и алгоритмы уже придумали "дядьки" из 60-х. Но! Это я не к тому, что в отрасли настал кризис, нет! Наоборот — это значит что отрасль сформировалась как таковая, "повзрослела" что-ли, и это здорово. И теперь она будет именно такой (по крайней мере до очередной метаморфозы связанной с кризисом бизнеса в ней, например, но это уже другая история).
Теперешних программистов можно понять. Многие, например, неявно заинтересованы в том чтобы новая версия windows содержала больше ошибок, занимала больше места на диске и в памяти и работала медленнее (и похоже так и будет — исключений здесь не бывает так как того требуют ускорения сроков разработки, увы чудес не бывает). Это позволит им кормиться "на ней" разрабатывая такие же "неэффективные" программы (по занимаемому объему и быстродействию) потому что пользователь вынужден будет улучшить свой компьютер. А значит писать эти программы они будут еще быстрее — а это сейчас главное! Программирование как таковое многим уже не интересно — интересны лишь деньги, которые можно на этом заработать. Зачем что-то оптимизировать, искать ошибки, прорабатывать архитектуру? Как сейчас говорят — "пипл хавает" и баста, главное опередить (ну или скупить на корню) конкурентов. Программирование уже давно не наука, а бизнес!
PD> И вот тогда этот неэффективный стиль программирования даст себя знать! PD>Сейчас можно просто рассуждать — чего я буду 20 Мбайт экономить, если PD>пользователь без проблем 256 может докупить ? А вот когда опять в жестких PD>лимитах работать придется — окажется, что некоторые программы, которые вполне PD>могли бы быть написаны, написаны не будут, или же будут написаны лет через 10 PD>после того момента, когда они могли бы появиться! Потому что эффективно PD>работать большинство не умеет. Привычки у них такие — что нам стоит лишних PD>десяток Мбайт взять!
Вы в корне не правы. Когда (и если) наступят такие времена, что надо будет делать снова "хорошие" программы — за дело опять возьмутся профессионалы, только теперь уже матерые программисты-профессионалы (опыт-то есть!). И они напишут и компилятор паскаля в 64к и еще много чего другого. Людей такого скалада не много, но они есть, и когда часы пробьют — они окажутся востребованней, чем те кто пришел в программисты за легкими деньгами...
Маленький совет сочуствующим автору. Вы любите чистое творчество, сложные неординарные задачи, непаханные поля новых технологий? Уходите из программирования. Я имею ввиду не "телом", а "душой". Т.е. можно продолжать зарабатывать на этом поле деньги, а тем временем прорабатывать новые, хотя бы смежные, отрасли. Чертовски приятно видеть как происходит становление новой технологии! И там есть где разгуляться пока туда не нагрянули люди с огромными мешками денег и не началась грызня за эти самые мешки :-)
Да и еще. Я не хотел обижать нынешних массовых программистов. Даже пресловутых индусов. Никоим образом! Они молодцы и достойно развивают отрасль ставя производство программ на конвейер и шлифуя его и оттачивая в мелочах в т.ч. и на своих ошибках. Это титанический труд!
PD>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>это возможно!
Перефразируя, можно дать более правильный совет (ИМХО): работу надо стараться делать хорошо, потому что плохо оно само получится. А эффективность программ здесь не причем, если сейчас выгоднее писать быстрее — значит именно это и надо делать. Да и где четкие критерии этой самой эффективности? Они же меняются со временем... Надо писать соответственно текущему уровню развития отрасли. Раньше это было компактно и не спеша, сейчас дешево и быстро, завтра будет еще что-то и т.д... Но при этом — если вы профессионал вы должны уметь писать по-любому из этих критериев и держать руку "на пульсе".
p.s. Все вышеизложенное — это сугубо мое мнение, хотя я старался быть максимально объективным. Ничего личного.
Здравствуйте, Павел Кузнецов,
>> Излишней является любая оптимизация, которая не направлена на изменение ситуации, при которой система не способна уложиться в определенные в проекте временные рамки на том оборудовании, для работы на котором она предназначена.
ПК>Только та, которая стоит дополнительного времени при разработке.
ИМХО любая оптимизация будет стоить дополнительного времени, если проектировать и делать "абы работало".
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
Здравствуйте, savaDAN, Вы писали:
DAN>И чем же она может выйти боком? тем что народ разучится писать эффективные программы? Но это ж не секрет дамасской стали. DAN>К тому же большинство из нас писать эффективные программы могут, и даже любят... но им этого менеджеры не дают... и правильно делают, я писал выше почему.
Есть разница оптимизить, потому что это нравится и потому что это надо. Любят оптимизить именно там, где нравится, доводя эффективность до предела в (почти) неиспользуемом коде, а сам код до предельной нечитаемости.
DAN>А тенденция не поменяется пока не закончатся гигагерцы и гигабайты.
Лично я воспринял исходный пост, как предупреждение, что понятие "оптимальный", в частноти, у меня сейчас совсем не такое, как было у автора лет 20 в фигом назад, и даже не такое как было у меня лет 10 назад. Кое что потеряно ради быстрого написания приемлимого для современных компов кода. Призыв писать программы эффективно на сколько возможно, я понимаю как не расслабляться и быть готовым думать про эффективность больше. Именно думать, а не наворачивать супер алгоритмы где умею.
Здравствуйте, pp2, Вы писали:
pp2>Варианты конечно всегда есть, но даже если софт "свой", и на продажу в конечном счете, то рынок одинаково "безжалостен" ко всем. Как опередить конкурентов? Как предложить больше всяких фич и сэкономить бюджет проекта? Ну и т.д., соответственно "творчество" здесь весьма на любителя. И кстати частично даже не в области программирования вообще.
+1
pp2>Если софт открытый или не на продажу — то да, возможны варианты. Хотя общая тенденция на лицо.
Тенденция на лицо, но это совсем не означает, что ей нужно безусловно поддаваться. Тут, имхо, так: либо ты ищещь оправдания, либо возможности. Возможности искать труднее. Я, например, пытаюсь. И поэтому мне не интересно думать о том, что искусство становится ремеслом, места для фантазии не остается, индустрия выживает изобретателей и пр. Это не конструктивно.
Среди заповедей для художника от Сальвадора Дали была такая: "Художник -- рисуй!"
Очень к месту, имхо.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>> char szTotal[1000]; PD>> char * szStrings[3] ={"abc", "def", "ghi"}; PD>> int nStrings = 3; PD>> char* pCurrent = szTotal; PD>> for(int i = 0; i < nStrings; i++) PD>> pCurrent += sprintf(pCurrent,"%s",szStrings[i]);
S>Гм. Мне не хотелось бы прослыть человеком, приносящим дурные вести, но ты только что продемонстрировал способ внести в программу buffer overrun vulnerability. S>Если не дай байт кто-то изменит содержимое szStrings так, что оно перестанет помещаться в szTotal (который ты предусмотрительно разместил на стеке), то спринтф чудесным образом разрушит стек.
Это уже совсем несерьезно. Человек спрашивал, как технически, т.е. с помощью каких средств языка С++ можно такое сделать. Я ему и показал. Неужели я не понимаю, что 1000 может не хватить ????
S>Это, на мой взгляд, не вполне адекватная плата за однопроходность. S>Еще я бы хотел отметить, что в твоем примере все живет за счет сверхмалых размеров строк. На таких объемах можно хоть перевыделениями заниматься — существенного падения производительности ты не добъешся. А как только мы заговорим о более реалистичном мире, где действительно станет нужна оптимизация строковых операций, выделение фиксированного буфера в стеке моментально исчезнет из поля нашего зрения.
А, прошу прощения, если не знать или хотя бы предполагать общий размер, то задача вообще не разрешима в однопроходном варианте. Потому как нельзя копировать в буфер, не выделив его предварительно. А длины в С++ не хранятся, в отличие от С#. На Паскале можно, там они хранятся.
S>Поэтому настоящие программисты всегда используют нормальный оо-код из std:: вместо всяких спринтфов и прочей небезопасной ерунды.
Нормальные герои всегда идут в обход (C) Доктор Айболит.
S>З.Ы. Кстати, поиск целого в массиве тоже лучше честно делать через S>
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>это возможно!
Все зависит от задач, от времени и еще кучи других факторов.
Где-то можно легко пожертвовать эффективностью.
Где-то не получится.
Вот у нас пишут систему на PC и для железяки со считанными килобайтами.
Угадай где мы жестко оптимизируем, а где в очень редких случаях.
В общем призыв "оптимизируйте везде" так же далек от жизни,
как и призыв "забейте на оптимизации и просто докупите память".
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>> И действительно, как было не признать! Пока программа небольшая и в память PD>>помещается — ладно, живите и радуйтесь! Ну а как побольше стала ? Тут-то и PD>>придется признать свое бессилие. А гуру, им что, всегда что-нибудь придумают. PD>>Кто-нибудь из нынешнего поколения слышал про "самоубийство программ" ? Нет, это PD>>не стирание EXE-файла во время его работы. Это когда программа во время своей PD>>работы использует память, занятую своими командами (которые уже отработали и PD>>больше не потребуются) под свои данные. GZ>У меня это называлось overlay.
Нет, оверлей — это нечто иное. Я этим на СМ-4 и ЕС-1022 занимался, это вполне легальное действие, даже ассемблер не требуется. А самоубийство только на ассемблере делалось, даже ИМХО не на ассемблере тогда, а просто в кодах.
PD>> Дудки вам, а не 640 Кбайт. В 640 Кбайт сейчас умеют только "Hello, PD>>World" укладывать! Пока несколько десятков Мбайт не будет, и не подходите. GZ>Ты Турбо-Vision пользовался?
Немного.
GZ>Я тоже горячился когда оказалось что exe файл для Delphi был больше мега(сейчас не помню, но для тех времен очень много). Но то, что я мог мышью быстро собрать приложение и получить за него деньги перевешивало. Как программисту который уважает свое творчество, это плохо. А вот для человека который пытается на хлеб масло намазать, чрезвычайно хорошо.
GZ>NT 4.0 на 8 мегабайтах не работала, а обслуживала саму себя. И то, если сервис паки не ставить.
Ну пусть на 16
GZ>Так оно места то много не занимает. Оно действительно эффективно. А вот если говорить о сопутсвующих процессах, типа сервисов и т.д., или тех же картинок, то это и есть увеличение. С установкой сервис паков и добавления функциональности, ситуация выравнивается.
Чудно. А могу я эти сервисы безболезненно удалить, и освободить Мбайт так 50-60 ? Немного — получится, а остальные, увы, обязательны для системы. А мне, в общем, все равно, как это называется, ядро или сервисы, лишь бы занимали они поменьше.
GZ>Если пользователь будет одновременно работать с моей программой, с 10 вордами, 50 акцессами, и 30 экселами одновременно, то у него моя программа будет тормозить. Скажи мне, это я в этом не виноват?
А какое это имеет отношение к тому, о чем я говорил ? Если машина загружена сверх ее реальных возможностей — конечно, ты не виноват. А вот если реальные возможности машины позволяют загрузить 10 копий твоей программы (без вордов и эксцелов), будь она эффективно написана, а она написана так, что и 3 копии тормозят — виноват ты.
Ты можешь сформулировать когда программу можно считать избыточной?
Попробую.
Программа избыточна, когда она
1. Использует памяти больше, чем требуется.
2. Загружает процессор больше, чем требуется.
3. Хранит на диске файлы большего размера, чем требуется.
А требуется — по характеру задачи.
PD>>Или вот другой пример — с умножением матриц GZ>Вроде дошли до того, что здесь кэш процессора играет слишком большую роль.
Дошли до того, что здесь виной перегрузка в кэше оверхеда на класс массив.Но по мне хоть кэш, хоть процессор, хоть винчестер, хоть дух святой. Не желаю я причин знать , а просто факт констатирую — машина это может в несколько раз быстрее делать, значит и должна делать!
GZ>Это взгляд со стороны. Разработчики все понимают. Но понимают и другое. Здесь уже несколько раз обсуждалось. Ошибиться в том, что ты неправильно определил место торможения, потратил много времени и сил на работу которая не нужна, значительно хуже. Поэтому лучше сначало сделать, а потом заниматься выявлением узких мест. А также оптимизацией памяти, если ее оказалось недостаточно.
Ничего у вас не получится. Потому что эти узкие места вы, может, и найдете, а вот общий уровень все равно с оверхедом будет. Там Мбайт, здесь Мбайт — в итоге 100 Мбайт и виновных нет.
PD>>Хороший, кстати, пример — ICQ. Написана она не на .Net ИМХО (давно GZ>Жадные вы. Че вам памяти жалко? GZ>Во первых, ICQ — это глюк официально выходящий в альфа-бета видах. Притом накрученная функциональностей, которая особо никому и не нужна.
А у ICQ вообще когда-нибудь не-беты были ? У меня что-то впечатление такое, что она только из бет и состоит
GZ>Во-вторых, не стоит по одной-двух программах делать выводы о отрасли в целом. Во времена MSDOS, были свои глюкавые монстры.
Ну другие примеры уже привели, не буду повторяться.
PD>>Мне тут VladD2 упрек такой кинул — дескать, писать надо , не PD>>слишком думая об эффективности, а потом узкие места можно оптимизировать. GZ>Подпишусь.
Имеешь право
GZ>Будет. Важно даже не то, что в бумажках написано. Важно доволен ли пользователь программы.
Пользователь доволен. Вполне. И если он у тебя один — решай с ним все проблемы. А вот когда речь о продуктах, используемых в миллионах копий идет — тут задавать вопрос, доволен ли пользователь — все равно, что спрашивать, оуениваете ли вы положительно работу ГосДумы . Отдельно одной программой доволен, другой — доволен, третьей доволен, все вместе запустишь — недоволен. Жалуйтесь кому хотите, хоть господу богу.
GZ>Аналогия неуместна. Важно насколько клиенту важно чтобы он летал. Зачастую заказывают атомную подводный крейсер, а тебе выкатят Ту155 с 5 подводными винтами. И вроде двигается быстрее чем нужно. И летает, что не заказывали. И вроде винты красивые и их больше чем нужно. Но не плавает. Ну не успели научить.
Бывает и такое. Как в известном анекдоте, как ни собираю, а пулемет получается. Но почему аналогия неуместна — не понял.
GZ>Не согласен. Уже вверх перестали развиваться такими темпами. Зато начали развиваться вширь.(двухядерные процы)
Я же не утверждаю, что я прав. Дай бог, чтобы я неправ в этом был.
GZ>А на 512 легко. Но вопрос в другом. Если ты пишешь компилятор паскаля, то можно и в мег запихнуться. Но если ты будешь писать сервер приложений, и уместился в мег, то тебя в первую очередь должны выгнать. И я буду первым бежать и махать поганой метлой. Если тебе дали компьютер, с гигабайтом памяти, и с несколькими процессорами, то повышай эффективность используя все что тебе дали. Делай большие кэши, пользуй несколько потоков.
Если я это сделаю, и все же уложусь в мег, ты меня все равно выгонишь ? Если я вместо буфера в несколько мег, в котроый все читается, использую MMF, в котором доступ будет только к тому, что реально требуется — тоже выгонишь ?
Здравствуйте, McSeem2, Вы писали:
MS>Не согласен. Я бы сказал, что это вещи вещи независимые — "этого научить проще тому-то, чем вот этого — противоположному". Здесь главное — чтобы человек обладал некими общими инженерными навыками. Фишка в том, что если человек умеет оперировать байтами в памяти, он как минимум знает, как устроен компьютер. И если он является инженером по своей сущности, то он очень быстро поймет, почему этого не надо делать в дот-нет. И наоборот, если человек начал с дот-нет, но при этом он обладает некими инженерными знаниями, он очень быстро разберется в том, как надо делать эффективно. Встречаются упертые личности — одни на ASM, другие — на C#, но они — не инженеры. И вопрос переучивания — он больше психологический чем технический. Если человек является инженером по своей психологии, то он переучивается легко — хоть туда, хоть сюда. Если же это для него туго, то наилучший способ его задействовать — это поставить на ковейер — пусть работает как машина Тьюринга и выполняет команды. Не хочет? — ну и ладно, найдем другого. Все это и ко мне тоже относится — так что просьба не принимать на личный счет.
Я конечно и не спорю, если человек вменяем — переучить его не проблема. Но слишком уж часто охота за байтами превращается в навязчивую манию, с которой чертовски трудно бороться — по себе знаю . Именно поэтому обучение надо начинать "сверху", а не "снизу", ИМХО
Здравствуйте, gear nuke, Вы писали:
GN>ИМХО не стоит забывать, что развитие часто идёт по спирали...
Это не развитие идет по спирали, это просто отдельные люди любят повторять старые и давно известные ошибки...
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Но вот одно либо я недостаточно четко изложил, либо меня не поняли, либо не хотели понять. Я не призыаваю к тотальной оптимизации, это просто глупо, в конце концов. И те, кто меня в этом упрекают, зря стучатся в открытую дверь. Я выступаю за то, чтобы код на своем уровне писался эффективно. Чтобы не использовались явно избыточные по памяти или времени конструкции, когда это совсем не обязательно и вполне ясно, как без них обойтись, отнюдь не поступаясь при этом ясностью и четкостью.
Д>Что в лоб, что по лбу — особой разницы я не вижу
Оптимизация всего и вся либо же не использование заведомо неэффективных конструкций — и ты не видишь разницы ? Ну, тогда сложно сказать что-то еще.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Оптимизация всего и вся либо же не использование заведомо неэффективных конструкций — и ты не видишь разницы ? Ну, тогда сложно сказать что-то еще.
А ты прочитал статью? Там есть как раз про "заведомо неэффективные конструкции". Почитай, в частности, про страшный алгоритм сложности f(n^3)
D>Я абсолютно согласен с ортимизацией "где надо", речь не об этом. В исходном посте посте говорилось о тенденции, о появившихся привычках и том, что понятие "оптимальный" просто забывается, уходит вслед за 1Mhz компами и 640Кb памяти. И что эта тенденция очень может выйти боком в свете физических пределов GHz и Gb.
И чем же она может выйти боком? тем что народ разучится писать эффективные программы? Но это ж не секрет дамасской стали.
К тому же большинство из нас писать эффективные программы могут, и даже любят... но им этого менеджеры не дают... и правильно делают, я писал выше почему.
А тенденция не поменяется пока не закончатся гигагерцы и гигабайты.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Мда. Энтузиасты и вольные художники формируют эту индустрию. ЗХ>Ну да к вечеру вернется McSeem2, он тебе подробнее объяснит
ЗХ>Конечно, а зачем?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Перекодирование строки из файла из 866 в 1251.
PD>Все что я нашел, сводится к
PD>public string MyDecoder(string str) PD>{ PD> byte[] b = Encoding.GetEncoding(866).GetBytes(str); PD> str = Encoding.GetEncoding(1251).GetString(b); PD> return str; PD>}
Гон. В файле нет строки. В файле есть байты.
Поэтому достаточно использовать ровно один Encoding.Convert.
Если ты из файла получил строку, то ты сам виноват — делаешь три Convert вместо одного.
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Nickolay Ch, Вы писали:
NC>>Буду краток: писать код надо так, чтобы из него можно было получить максимальную денежную прибыль. GZ>Хорошие слова. Только не надо под ними подразумевать скорость написания кода. Действительно, существует достаточно много продуктов сделанных тяп-ляп. Да, они выиграли тактически. Они впихнули полуживое решение и получили за них деньги.
Уже 2 раза тут писал, что под этим понимается каждый раз разное. И далеко не всегда скорость написания, так же как и далеко не всегда "нересурсоемкость" и т.п.
NC>>Уважаемый mrozov правильно написал, что времена любителей позаниматься сексом с компом прошли в индустрии программирования. GZ>Нет, не прошли. Просто пришла мода на другие извращения. IMHO
И слава богу (С)
NC>>Энтузиастам и "вольным художникам" не место в индустрии. GZ>Место. И притом денежное место. Индустрия большая. Даже в замой замшелой конторе с шизофреническими процессами разработки, есть место творчеству. Просто у архитектора — одно поле для творчества, у программиста — другое. У меня есть друзья, я по одному взгляду могу сказать кто какой код писал. Потому как каждый индивидуален в своих предпочтениях.
Вообще-то особенно при работе в команде код должен быть подчинен стандарту. Суть в том, что основная часть производства софта это именно индустрия, масс-продакшн.
Выдержали отдельно взятые ремесленники конкуренцию с мануфактурой? А ведь каждый из них был МАСТЕРОМ?
Да, и сейчас есть, мастера, делающий некие продукты руками, скажем какую-нибудь резную мебель, не придерживаясь стандартов производства и т.п. Только много ли их? И много ли они производят в процентном соотношении от всей произведенной мебели?
mrozov,
> Излишней является любая оптимизация, которая не направлена на изменение ситуации, при которой система не способна уложиться в определенные в проекте временные рамки на том оборудовании, для работы на котором она предназначена.
Только та, которая стоит дополнительного времени при разработке.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
pp2,
> Многие, например, неявно заинтересованы в том чтобы новая версия windows содержала больше ошибок, занимала больше места на диске и в памяти и работала медленнее (и похоже так и будет — исключений здесь не бывает так как того требуют ускорения сроков разработки, увы чудес не бывает)
В отношении количества ошибок прогноз не вполне оправдывается: чем дальше после Windows 95, тем их меньше. В следующих версиях обещают еще лучше, т.к. вкладывают деньги в повышение качества разработки.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Кстати, вот еще пример. Из официального руководмтва Микрософт, между прочим
PD>Есть строка myString в формате CSV
PD>myDataSet.Tables["Table 1"].Rows.Add(myString.Split(char.Parse(",")));
PD>Берем строку, делаем из нее массив строк и по запихиваем этот массив в Rows. А нельзя ли без того, чтобы массив создавать ? В C++ я бы просто прошел по этой строке strtok и добавил строки — без всяких дополнительных массивов.
Павел. Ситуация со строками значительно интересней. Строка — это неvalue объект. И она не будет копироваться. Просто передается ссылка. А выделение маленького объекта в С# на порядок дешевле чем в С++. Поэтому это достаточно простой способ и эффективный.
Функции strtok нету(неприятная функция, я ее не люблю, в таких случаях работаю обычным поиском), точно также как нет split в С, но написать такую функцию легко. В принципе,
int i, l=0;
while ((i=myString.IndexOf(",", l))!=-1)
{
rows.Add(myString.Substring(i, l-i);
l=i;
}
Делает именно то, что заказывали. Без массива.
Сравните с тем-же самым в C++ только с strtok.
С уважением, Gleb.
ЗЫ. Интересно, если я напишу так
int l, i=0;
while ((i=myString.IndexOf(",", (l=i)))!=-1)
rows.Add(myString.Substring(i, i-l);
Здравствуйте, RobinBobin, Вы писали:
RB>Здравствуйте, Pavel Dvorkin, Вы писали:
RB>
RB>На C++ конкатенацию массива строк в новую строку (я имею в виду не string из STL, а char*) я все же напишу однопроходным алгоритмом и при этом не будут использоваться никакие промежуточные буферы.
RB>Как ?
char szTotal[1000];
char * szStrings[3] ={"abc", "def", "ghi"};
int nStrings = 3;
char* pCurrent = szTotal;
for(int i = 0; i < nStrings; i++)
pCurrent += sprintf(pCurrent,"%s",szStrings[i]);
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Sinclair, sorry, а не мог бы ты подсказать, как здесь эффективно сконкатенировать все же массив строк при том, что количество их определится в момент конкатенации? S>С массивом все вообще просто. См. string.Join.
+
PD>>Твой первый пример хорош, но там жестко 3 строки. На C++ конкатенацию массива строк в новую строку (я имею в виду не string из STL, а char*) я все же напишу однопроходным алгоритмом и при этом не будут использоваться никакие промежуточные буферы. Потому что задача по определению однопроходная. S>Это как, интересно?
Не понял, ты спрашиваешь, как в C++ сделать ? Я уже отвечал.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Если у программиста проблемы с ДНК, то лечится это не инструментальными средствами. Инструменты, напротив, должны давать возможности тем программистам, у которых с ДНК все в порядке.
А вот это — более чем спорно. Я бы даже сказал, что подобные заявления отдают манией величия =)
Не думаю, что стоит вот так категорично говорить о том, что вам должны инструментальные средства.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD> char szTotal[1000]; PD> char * szStrings[3] ={"abc", "def", "ghi"}; PD> int nStrings = 3; PD> char* pCurrent = szTotal; PD> for(int i = 0; i < nStrings; i++) PD> pCurrent += sprintf(pCurrent,"%s",szStrings[i]);
Гм. Мне не хотелось бы прослыть человеком, приносящим дурные вести, но ты только что продемонстрировал способ внести в программу buffer overrun vulnerability.
Если не дай байт кто-то изменит содержимое szStrings так, что оно перестанет помещаться в szTotal (который ты предусмотрительно разместил на стеке), то спринтф чудесным образом разрушит стек.
Это, на мой взгляд, не вполне адекватная плата за однопроходность.
Еще я бы хотел отметить, что в твоем примере все живет за счет сверхмалых размеров строк. На таких объемах можно хоть перевыделениями заниматься — существенного падения производительности ты не добъешся. А как только мы заговорим о более реалистичном мире, где действительно станет нужна оптимизация строковых операций, выделение фиксированного буфера в стеке моментально исчезнет из поля нашего зрения.
Поэтому настоящие программисты всегда используют нормальный оо-код из std:: вместо всяких спринтфов и прочей небезопасной ерунды.
З.Ы. Кстати, поиск целого в массиве тоже лучше честно делать через
Здравствуйте, Павел Кузнецов, Вы писали:
>> Заметка из жизни. Если у программиста проблемы с ДНК, то C# многое прощает, а вот шаблоны в С++ многое усугубляют.
Не думал что подобная заметка из жизни вызывет флейм о вилках и детской посуде.
ПК>Если у программиста проблемы с ДНК, то лечится это не инструментальными средствами. Инструменты, напротив, должны давать возможности тем программистам, у которых с ДНК все в порядке.
Только вопрос в том, что для кого программирование работа, а для кого-то призвание. И первых значительно больше чем вторых.
Так что если говорить о промышленных языках, то я бы сказал что они есть компромисс — помочь первым, и не мешать вторым.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, pp2, Вы писали:
pp2>>Маленький совет сочуствующим автору. Вы любите чистое творчество, сложные неординарные задачи, непаханные поля новых технологий? Уходите из программирования. Я имею ввиду не "телом", а "душой". Т.е. можно продолжать зарабатывать на этом поле деньги, а тем временем прорабатывать новые, хотя бы смежные, отрасли. Чертовски приятно видеть как происходит становление новой технологии! И там есть где разгуляться пока туда не нагрянули люди с огромными мешками денег и не началась грызня за эти самые мешки
E>Давайте это Ричарду Столлману (GCC, emacs), Линусу Торвальдсу (Linux), Тео да Радту (OpenBSD), Гвидо ван Россому (Python), Ларри Уоллу (Perl), Якиро Матцумото (Ruby), ...(список можно продолжать)..., раcскажем. А то мужики, право слово, фигней страдают. Надо их жизни-то научить.
E>
E>Ребята, если вы относитесь к программированию как к обычной работе, средству заработка, то и относитесь себе так и дальше. Зачем же подобные советы давать
Т.к., в основном, в этом разделе пустой фелйм, то могу ответить Вам симметрично:
Если вы относитесь у программированию как к искусству, то и относиесь себе и дальше, советы давать то зачем
Мы с вами будем одинаково правы в подобных советах.
Я достатосно резко написал так потому, что исходный призыв был столь же эмоционален сколь и пуст.
"Пишите эффективно" — и Столлман пишет эффективно, и армия индусов в МС(или где там еще), просто "эффективность" у каждого своя...
Всех то стричь под одну гребенку зачем?
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Например, есть выбор: написать сортировку "пузырьком" или использовать библиотечную std::sort. Первое делать дольше и в большинстве случаев работать будет медленнее, чем второе.
Вот, кстати, хороший пример Вы привели. А если человек не понимает, что и почему лучше, он запросто может реализовать то, что первое придёт в голову (пузырёк) .
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
Cyberax,
>> Гм. Мне не хотелось бы прослыть человеком, приносящим дурные вести, но >> ты только что продемонстрировал способ внести в программу buffer >> overrun vulnerability.
> Вот политкорректный вариант: >
iZEN wrote:
> Есть такая парадигма: service-oriented architecture (SOA). > Она есть и успешно работает в MacOS X. Грубо — это когда пользователь > вместо покупки программы за $400 с навороченным интерфейсом и > ненужными (для него) фичами обходится мимтемным сервисом, но с нужной > ему фичей за $25. > Сервис проверки орфографии ВО ВСЕХ текстовых полях, а не только в > конкретном текстовом редакторе одной известной фирмы — вот одно из > следствий такого подхода. Маленький и не тормозит.
Надо сказать, что API для Вордовской системы проверки правописания
свободно доступны. У меня, например, они прикручены к Far'у.
Здравствуйте, raskin,
>> *почему* до сих пор нет ни одного компилятора использующего это эффективно?
R>Современное управление кешем неполно (у кеша всегда есть и своё мнение R>кроме prefetchnta) и непереносимо, поэтому никто не заморачивается?
Вот именно. ИМХО для этого по-хорошему нужен JIT компилятор, а такое есть пока только под .NET, можно сказать. В зачаточном состоянии, скорее всего. Обычные компиляторы сколько лет до ума доводили.
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
Здравствуйте, GlebZ, Вы писали:
GZ>Да уж. Действительно сильно искуственный пример. GZ>strok — злобная функция, так как она использует static данные на уровне CRT.
Хуже. Она использует __declspec(thread). Иначе, сам подумай, что будет, если ее начнут из разных потоков вызывать
>И соответсвенно, два выполнения strtok — прямой путь к нетрадиционному сексу. Лучше всего вообще забыть о ее существовании.
Вообще да. Я свою писал
GZ>Именно. А если у кого-то была ссылка на строку, то тебе надо делать копии. Но чаще придется делать копии, из-за того что ты не можешь предположить, будет строка изменяться, или нет.
Во многих и даже очень многих могу
const char* p — и я имею право предположить, что не будет.
GZ>По крайней мере одну придется делать(и не дай бог что TestWord тоже использует strtok):
Да зачем же ? Пусть TestWord себе благополучно эту строку исследует (например, является ли слово палиндромом). Начало — p, конец — '\0', зачем мне тут подстроки в отдельный буфер копировать, когда и на месте все ясно ?
Pavel Dvorkin,
> когда речь идет о коде, разработанном для данного проекта, то во многих случаях Copyright на этот код получит заказчик. Так что повторно его использовать законным путем можно только в том случае <...>
Пожалуй, при разговорах о повторном использовании речь идет о других проектах, делающихся "для себя". Особенно актуально это для (относительно) маленьких команд и/или (относительно) долгоживущих проектов.
> Интересно было бы узнать — насколько часто программисты действительно повторно используют свой код? Т.е не идеи из него используют для нового кода, а прямо-таки класс/функцию/компонент свой берут и в новый проект втыкают.
Мы стараемся делать это настолько часто и в таком объеме, насколько у нас получается, т.к. это напрямую связано с эффективностью работы над очередным проектом (больше повторно используемого кода -- меньше работы над данным проектом).
> Естественно, речь не идет о библиотеках.
При достаточном приложении усилий к повышению удельного "веса" кода, используемого повторно, он почти неизбежно со временем превращается в более-менее изолированные компоненты, библиотеки или фрэймворки (в последнем случае об изоляции, естественно, речь идет в значительно меньшей степени).
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
PD>Игорь, я вовсе не утверждаю этого И более того, если есть 1 млн. программистов на нем, то они за что-то деньги свои получают. Я о другом говорю. До сих пор была определенная разница между тем, что можно было хотя бы в принцие писать на VB и тем, для чего VB не может рассматриваться как среда разработки вообще.
PD>Например, я сильно сомневаюсь, что Adobe могла бы рассматривать VB как среду для разработкт своих продуктов. И даже на порядок более простой какой-нибудь file downloader тоже на VB никто писать не стал бы. Не то средство.
если приглядеться — у формы автоапдейтера Microsoft AntiSpyware просвечивает VB икона =)
PD>А вот будет ли Adobe переписывать PhotoShop на .net — не знаю. Надеюсь, что нет
главное чтобы программа была удобная, а на чем ее переписывали — мне уже не интересно.
Здравствуйте, Дарней, Вы писали:
Д>расшфировал аббревиатуру — правильно. Понял смысл — неправильно. Д>Не вижу вообще смысла спорить на эту тему. Есть общепринятое значение, которое вкладывается в это выражение. А если ты решил для себя, что будешь называть стол стулом — то это исключительно твои частные проблемы.
Допустим, что я понял это неправильно (хотя, честное слово, впервые об этом принципе я прочитал еще в 80-е годы, и в книге, которая к Unix не имела отношения. В таком случае будь добр объяснить, в чем неправильность моего понимания. Заявлять же — "ты неправ, и я не вижу смысла соприть на эту тему" — не есть аргумент.
Д>раз в месяц? да вы, батенька, оптимист
Нет, я ее просто не держу. . Поэтому статистики не знаю. Триллиан падал за несколько лет раз 5, и то обычно при Windows shutdown (что-то они там не учли, видимо)
PD>>Ну несерьезно это. Есть страна, для которой я это делал. Есть у них в стране некая информация (извини, но деталей рассказывать не буду). Эта информация там появилпась, когда еще никаких компьютеров на свете не было, а может, и автомобилей не было. И вот я эту информацию в некий буфер заношу. И то, что она никак не может быть больше, чем 500 символов — гарантия в 101%. Никогда не может, ну так же, как имя русское не может быть длиной в 500 символов. А времени считать эту длину абсолютно нет, потому как на все про все мне дано 100 мсек. И в этих условиях ты все же будешь утверждать, что buffer overrun возможен ?
Д>сразу вспоминается случай, когда разработчики решили, что длина серии паспорта не может быть больше 10 символов (может быть и не десять, не помню точно) Д>А потом приехал парень из страны, где серия паспорта имела больше символов. И бедолага несколько месяцев ходил по инстанциям.
Ну и что ? Это лишь говорит о том, что они неверно оценили максимальный размер, только и всего.
Программа делается для России. Приведи ситуацию, в которой здесь возможен buffer overrun. Фамилию и имя, please , в студию.
Д>еще могу напомнить про случай, когда разработчики решили "ну не может эта переменная переполниться! ни никак! потому что этого не может быть никогда!" Д>а потом в траекторию полета внесли изменения, и аппарат с треском рухнул.
Ну и что, опять-таки ? См. мой пример с nScreenArea. Может, оно когда-нибудь и грохнется, на 4ГПикс дисплее. Но не будешь же ставить под контроль все арифметические операции и на каждую из них писать try-catch из-за того, что при некорректно заданных операндах это может вызвать ошибку ? Или впрямь будешь писать везде так
int nScreenWidth = ..., nScreenHeight = ...;
int nScreenArea;
try
{
nScreenArea = nScreenWidth * nScreenHeight;
}
catch(...) {}
Если да — то неудивительно, что это будет работать очень медленно. А если нет — то при работе однажды произойдет unhandled exception, и аппарат рухнет.
Д>намного, намного хуже. А ты не догадываешься, почему?
Нет. Не догадываюсь. Потому что любая ошибка может привести к любой наведенной ошибке. А если ты хочешь сказать, что при этом будет неопределенное поведение — так и при неправильных результатах будет то же, не только при выходе индекса.
PD>>А лишних Гбайтов я , кстати, не использовал. И лишней ОП — тоже. Ну разве что самую малость — буфер там был один с запасом в 64 Кбайта
Д>и зря. Вполне возможно, что это позволило бы поднять скорость без ущерба для надежности.
Может , и позволило бы, вот тут я с тобой готов согласиться. Но мне просто не надо было. Ну не сидеть же мне и придумывать, где бы еще лишних 100 Мб израсходовать
А вообще основное различие между моей и твоей позицией ИМХО в том, что ты хорошо знаешь некоторые общепринятые принципы, но рассматриваешь их как догму, которую нельзя переступать, как сказал Sinclair, под страхом смертной казни. Я же считаю, что при определенных условиях может случиться так, что делать придется, нарушая многие общепринятые правила, если это нужно для решения задачи и другого выхода нет. В конце концов лучше написать работающую программу не по правилам, чем по правилам ничего не сделать.
Здравствуйте, Sinclair, Вы писали:
PD>>Программа делается для России. Приведи ситуацию, в которой здесь возможен buffer overrun. Фамилию и имя, please , в студию. S>Очень просто. Этот код вызывается из обработчика веб формы регистрации пользователей.
Этот код НЕ вызывается из обработчика ВЕБ-форм. В этом случае так писать действительно не стоит. Этот код берет проверенные значения из БД, где для их хранения НЕ ОТВЕДЕНО 500 char. По-прежнему будешь утверждать ?
Я же говорю — истина конкретна. Если данные не вызывают доверия — один разговор. Если они вызывают доверие — другой. В моей задаче — вызывали.
S>Еще раз: то, как оно грохнется от целого переполнения, не приведет к исполнению постороннего кода.
Еще раз — истина конретна.
S>Будешь, если тебе дорого твое место работы. Причем кэтчить все места тебе не потребуется: как только придет информация о том, что где-то твое приложение упало, ты получишь нормальный стек трейс, в котором ясно будет указано место падения.
Придет. Равно как и в Win32 это можно сделать — StackWalk64 и вообще Send Error Report
S>Это позволит тебе очень быстро (по сравнению с анализом дампа) локализовать причины, и либо переписать код (например, используя long вместо int), либо вставить в нужных местах проверки (например там, где принимаются размеры).
В общем, мы Вас не защищаем уже от багов, мы лишь обеспечиваем, чтобы Вы могли их найти, когда приложение рухнет
PD>>А вообще основное различие между моей и твоей позицией ИМХО в том, что ты хорошо знаешь некоторые общепринятые принципы, но рассматриваешь их как догму, которую нельзя переступать, как сказал Sinclair, под страхом смертной казни. Я же считаю, что при определенных условиях может случиться так, что делать придется, нарушая многие общепринятые правила, если это нужно для решения задачи и другого выхода нет. В конце концов лучше написать работающую программу не по правилам, чем по правилам ничего не сделать. S>Ты не прав. Если влезть в исходники .Net, то можно увидеть и unsafe, и unchecked. Как раз для того, чтобы поднять производительность. Это не переступание догм, это подробное следование им. Потому, что отмененные такими опциями проверки делаются вручную. Сделать правильную программу быстрой легче, чем быструю — правильной.
S>Потому, что обо всех небыстростях тебе расскажет профайлер, а о неправильностях — пользователи и хакеры.
ИМХО не стоит продолжать. Не договоримся. Разные позиции. Я готов с уважением относиться к твоей, но признавать ее как догму не могу.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Да, увы, это так. Ты сделаешь быстрее, не спорю. И сэкономишь несколько К$ на своей зарплате. А в итоге 100,000 пользователей потратят несколько сотен тысяч $ на память, которую твоя программа заняла и не использует.
Гы 100 000 даже для газет это офигительный тираж. А при ценах софта — это просто суперприбыли. При таких доходах можно позволить себе разрабатывать софт хоть на ассемблере. Так что это случай особый. Намного чаще стречаются малотиражные разработки с ограниченными бюджетами или вообще заказные разработки. Вот их точно лучше разрабатывать на средствах обеспечивающих более высокую надежность.
PD>Да ведь нам говорят, что .Net — генеральная линия развития, а те, кому она не нравится — неандертальцы.
Не нестандартны, а не дальновидны, и как это не обидно звучит, не плохие аналитики.
PD> Вот и мне сегодня заказчик сообщил, что планирует нечто на .Net. Пока не знаю что. И не убедишь его, что это , м.б. не лучшее решение.
Может потому что твой заказчик более дальновидный человек?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Этот код НЕ вызывается из обработчика ВЕБ-форм. В этом случае так писать действительно не стоит. Этот код берет проверенные значения из БД, где для их хранения НЕ ОТВЕДЕНО 500 char. По-прежнему будешь утверждать ? WH>Я тут не поленился и сделал тест...
<skipped>
WH>Итого: C# в 2 раза быстрее чем С++ (при том что в C# при каждом сложении происходит выделение памяти и работа идет с юникодом) и самое главное то что код на C# безопасен.
Ну и ну... Уж чего-чего, а такого не ждал. Сравнивать конкатенацию строк и форматное копирование , включающее в себя разборку форматной строки и бог знает что еще!
Естественно, в моей программе никакого sprintf не было. А была моя собственная функция ConcatenateStrings. А sprintf я просто привел, чтобы показать, как это можно сделать.
PD>Нет. Это не жизнь, это парадигма такая. Несмотря ни на какте реальные условия — предполагать, что может все что угодно произойти По деревянному мосту танк пойдет, великан ростом в 33 метра явится, экран будет в 4Г пикселей и т.д. Если нужна максимальная надежность — я за. А в текстовом редакторе — извините, я против того, чтобы ради этой надежности он в размерах в 2 раза увеличивался и работал медленно. Потому как меня как пользователя больше достает, что мне памяти не хватает. что ползет как черепаха и т.д. А упадет один раз в месяц этот текстовый редактор — ну и черт с ним. В крайнем случае, сделайте, как в Ворде — сохранение в temp файл раз в n минут.
Решил помочь с примером:
Есть в физике понятие материальная точка — это точка, размерами которой можно пренебречь, соответсвенно есть просто точка — её размерами пренебрегать не стоит.
Соответсвенно, в Вашем коде, если я правильно понял спринтф — материальная точка .
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Pavel Dvorkin, Вы писали:
WH>ЗЫ Замеры производились 100 раз. Самые быстрые и самые медленные результаты отбрасывались, остальные усреднялись. WH>ЗЗЫ VS 2003
Вот мои результаты. Количество итераций цикла увеличил в 100 раз — не люблю я слишком малые значения
Ай-яй-яй!!! Как же это я так оплошал . Говорил, что , мол, нет времени на длину строки, проход мол, а ведь strcat — тоже проход, а оказывается, это быстрее, чем мой однопроходной код! Вот и делай после этого заявления про оптимизацию
Ничего, реабилитируемся. Просто уж строки слишком короткие.Заменим их на
Не так уж много, верно, процентов 10-15. Только вот здесь всего 2 строки конкатенируются, а у меня их было обычно 5-10. При concat второй строки проходится первая (поиск конца строки в szTotal) , при concat третьей — первая со второй, и т.д. В общем, двойной цикл
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
S>Хоть Вы и читтер уважаемый, ан все равно приятно увидеть Думмера, ( поглаживая свой БФЖ ), и вспоминать как БФЖ рулит на 7мом уровне в дедматч. Эххх.
Ради бога, переведи на русский, а то я даже не знаю, как на все это реагировать .
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Не так уж много, верно, процентов 10-15. Только вот здесь всего 2 строки конкатенируются, а у меня их было обычно 5-10. При concat второй строки проходится первая (поиск конца строки в szTotal) , при concat третьей — первая со второй, и т.д. В общем, двойной цикл
PD>Ну а вот что здесь C# дает
Здравствуйте, alexeiz, Вы писали:
A>Здравствуйте, GlebZ, Вы писали:
GZ>>Здравствуйте, alexeiz, Вы писали:
A>>>Так не пойдет. Чтобы было эквивалентно С++ варианту нужно ещё из StringBuilder получить String. GZ>>Почему?
A>В C++ версии на входе две строки на выходе одна. В C# — на выходе какой-то буфер (StringBuilder то есть). Чтобы его использовать как строку, нужно еще совершить преобразование.
Неа. На выходе один и тот же буфер содержащий строку. 100 байт стека. StringBuilder.ToString() — это не преобразование строки, а возврат буфера в виде строки. То есть все абсолютно аналогично.
Другой вопрос в Net с одним и тем же буфером создавать две строки нельзя. Поэтому аналогичным будет создание всегда новой строки.
Здравствуйте, alexeiz, Вы писали:
GZ>>Другой вопрос в Net с одним и тем же буфером создавать две строки нельзя. Поэтому аналогичным будет создание всегда новой строки. A>В этом тесте используется конкретная возможность C — создание строк на стеке с прямой целью, чтобы показать приемущество этого языка по сравнению с C#.
Да нет тут никакого преимущества. Преимущество имеет значительно более большее значение чем просто производительность. Про один буфер я прогнал. Можно и в одном буфере с помощью unsafe кода. Только использование unsafe дает большую производительность для конкретной задачи, но меньшую эффективность. Потому как нафигарить можно не хуже чем в C++.
Во вторых — это не создание строк, а заполнение буфера строками в цикле. Разница в этих терминах есть и существенная.
В третьих, если ты не получал ошибок когда ты выходишь за границы массива, значит ты никогда не писал на C. Так что данное упражнение отнюдь не показывает эффективность языка. Оно больше показывает его недостатки.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Проверять не буду, приму на веру. Все верно, я так и ожидал. Только одно имей в виду — StringBuilder постоянно хранит и изменяет поле длины. И это не бесплатно. Ты уже заплатил за вычисление этой длины вот здесь
По сравнению с копированием строк особенно если строки длинные это ничтожные затраты времени.
А если случится промах кеша то...
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, alexeiz, Вы писали:
A>Только с той разницей, что чтобы преобразовать буфер в строку в C, не нужно делать ничего. Например, нам надо передать строку после конкатенации в функцию foo(char*). В C — просто передаём этот самый буфер. В C# функция будет выглядеть как foo(string), и чтобы передать туда результирующую строку нам нужно сначала преобразовать StringBuffer в String.
Ты сильно преувеличиваешь стомость этой операции. Посмотри исходники StringBuilder.ToString() рефлектором.
З.Ы. Не все, что занимает меньше асм-команд, тратит меньше тактов
З.З.Ы. Не все вызовы одинаково дороги.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Проверять не буду, приму на веру. Все верно, я так и ожидал. Только одно имей в виду — StringBuilder постоянно хранит и изменяет поле длины. И это не бесплатно. Ты уже заплатил за вычисление этой длины вот здесь WH>По сравнению с копированием строк особенно если строки длинные это ничтожные затраты времени.
Нет, не ничтожные. На входе у тебя буфер из байтов или ushort. Строка, в сыром виде пришедшая, из файла, к примеру,. И длину ее найти можно только просмотрев символы в поисках некоего признака конца (0xD из файла). Это не копирование, но все же массовая операция. И делать ее у тебя кто-то будет, не ты сам, так кто-то из библиотеки. А вот я указатель на эту строку в memory-mapped файле возьму и дальше мое дело — искать ее длину или нет. Надо — найду. не надо — подожду пока что, может, и не понадобится.
Д>небольшой эксперимент показал, что лишенный проблем с безопасностью вариант с использованием std::string еще и работает куда быстрее, чем твой вариант — ценой потери небольшого количества памяти из тех гигабайтов, которые были у тебя в наличии, но которые ты не использовал Д>Вот мне и стало интересно — чего ты в конце концов хотел добиться своими "оптимизациями"?
Ты бы хоть внимательно посмотрел, что ты со string сделал
Это, между прочим, вызов конструктора. Который при этом вычисляет длину (поле string::_MySize) и теперь эта длина используется в операциях = и +=. А вызываешь этот конструктор ты один раз, а не 10000000 раз. Вот поставь так
std::string res;
for(size_t i=0;i<10000000;++i)
{
std::string firstName = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
std::string lastName = "22222222222222222222222222222222222222222222222222222222222222222222222222222";
std::string astr = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
std::string bstr = "11111111111111111111111111111111111111111111111111111111111111111111111111111";
res = firstName;
res += lastName;
res += astr;
res += bstr;
}
тогда и сравнивай.
Конечно, в этом случае и в моем коде надо сделать то же
только вот у меня будет в каждой из этих строчек одно-единственное присваивание указателю (szFirstName и т.д.), от длины строки вообще не зависящее, ну а у тебя массовая операция.
P.S. А вообще-то я придумал способ сделать еще быстрее. Примерно в 2 раза быстрее, чем мой вариант. Жаль, что в свое время до него не додумался.
Причем даже с нахождением длины, т.е. двухпроходный. Так что одна причина, почему я позволил себе потенциально небезопасный код, отпадает.. Вот только буфер все же придется оставить статическим — при попытке вставить в цикл выделение памяти и освобождение он проигрывает даже string. Так что полностью безопасным сделать все равно не удастся. Ну а кроме того, в реальной программе этот буфер жил очень долго, и строки в него добавлялись по мере надобности. И не только строки
Здравствуйте, alexeiz, Вы писали:
A>Приемущество языка С заключается в том, что он позволяет (не требует а позволяет) спуститься на уровень железа. Для С# это очень и очень ограничено. Все размышления о выходе за границы массива идут лесом. Это просто отдельный разговор.
Закон относительности. Можно повернуть и по другому. Преимущества C# то, что он не позволяет делать ошибки выхода за границы массива. Хотя и это неправда. Я прямо написал, что можно так делать, но это особый случай называемый unsafe кодом. Так что и C# умеет работать с памятью и указателями. Так что преимущества здесь нет.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Не совсем понял. Я так понял, что при дозаписи в StringBuffer меняется полученная раннее строка. Я не правильно понял суть ошибки?
Да. Неправильно. При любом дополнительном изменении StringBuilder после вызова ToString() выделяется новый буфер для изменений. Проблема примерно такая:
StringBuilder strBuilder=new StringBuilder("строка");
string str1=strBuilder.ToString();
string str2=strBuilder.ToString();
......
//здесь unsafe код который меняет строкуunsafe{fixed(char* pstr=str1){pstr[1]='F';}};
....
if (str2!='строка') Console.WriteLine("непонятный обломс");
этот код идентичен такому
StringBuilder strBuilder=new StringBuilder("строка");
string str1=strBuilder.ToString();
string str2=str1;
......
//здесь unsafe код который меняет строкуunsafe{fixed(char* pstr=str1){pstr[1]='F';}};
....
if (str2!='строка') Console.WriteLine("здесь мы хорошо знаем чем рискуем так как сознательно конкатенировали");
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>олько одно имей в виду — StringBuilder постоянно хранит и изменяет поле длины. И это не бесплатно. Ты уже заплатил за вычисление этой длины вот здесь...
И этот человек препадет в институте!
Какие там на фиг абстракции? Мы за за длинну платим!!!
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, gear nuke, Вы писали:
GN>Как я понял при первом прочтении, это означает в том числе и не злоупотребление ими?
Мне кажется слово "грамотно" подразумевает разумность использования. Конечно с дури можно и микроскоп не эффективно применять если им гвозди начать прибивать.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, GlebZ, Вы писали:
GZ>>>Влад. Только не надо говорить что все программирование ограничивается бизнес-приложениями. VD>>Я где-то такое говорил? GZ>Ты такое недвусмысленно подразумевал.
Телепат?
VD>>Одно дело знать, что такое блок памяти, а другое думать только ими. GZ>Неее. Я до сих пор думаю ими.
Слабо верится.
GZ>И это мне помогает понять язык. И тебе тоже.
И как тебе помогает понять скажем идиому интерфейсов раздумья о блоках памяти? Ну, или как это тебе помогает понимать паттерны проектирования вроде Посетителя?
GZ> А особенно помогает работать с массивами. И смотреть чтобы не было копирования больших данных. И тут абстракция не поможет. Здесь нужно иметь привычку делать так, чтобы потом кардинально не переделывать. Это в большей степени не проблема дизайна, а алгоритмическая проблема. Хотя меру тоже надо знать.
Я такой проблемы вообще не встречал. По-моему, и так понятно, что чем больше данных ты бестолку копируешь, тем болше времени и памти таратися зря.
GZ>Мы с тобой(судя по возрасту) плоды такого обучения. И я рад что прошел школу 286 процессора и CGA экрана.
От части, да. И мне стоило не малых усилий бороться с этими комплексами. Не раз ловил себя на мысли, что нехочу использовать виртуальный вызов просто потому что он медленее обычного. Причем с точки зрения дизайна отказ от виртауального вызова приводил к серьезному усложнению. Это смешно, но мне пришлось провести не один эксперемент чтобы осознать, что стоимость даже самого медленного виртуального вызова — это наносекунды, и что бы от него получить зримое замедление его нужно запихнуть в очень объемный цикл. Если же меня учили сначала создавать грамотный дизайн приложения, а потом уже оптимизировать по-необходимости, то таких проблем никогда не вознило бы.
Так вот я осознанно предалел (и продолжаю преодалевать) психологические проблемы борьбы за производительность. А некоторые товарищи даже не задумываются над необходимостью делать это. И то что эти товарищи старше лет на 10 нисколько их не оправдывает.
GZ> Очень обучает думать. Так кто там мерял скорость GDI+?
Ничего. Я потом опубликую результаты измерений и боюсь многие будут удивлены в какие мифы они верили. Забегая вперед скажу, что GDI+ не так тормозна как его многие описывают. При грамотном применении эта библиотека на сильно медленнее чем GDI.
GZ>Правильно действовать легко научить. Правильно думать — значительно труднее. И для системы алгоритм+доступные_ресурсы — нужно учиться думать.
Я не вижу потуги думать у учителя. И почти уверен, что именно этому в превую очередь научатся его ученики. Они всю жизнь будут вызимать биты из байтов. Ведь сломать привычку не так то просто. Любой кто бросал курить или переучивался печатать вслепую поймет о чем речь.
GZ>Думать абстракциями — также нужно учить. То же очень сложная штука. Но это и не обозначает отмену вышеописанного.
Я вижу, что товарищь учитель просто приципиально нежелает думать абстракциями так как они зачастую привносят накладные расходы.
Ведь езжу понятно, что быстрее выделения памяти в стэке быть ничего не может. Но это ведь не приводит разумных программистов к отказу от использования тех же строковых классов?
Я вижу следующую цепочку рассуждений.
Программы жрут больше ресурсов чем могли бы...
Надо писать так чтобы использовать минимально достаточный объем ресусров...
Абстракции зачастую увеличивают объем используемых ресуросв...
Так откажемся от абстаркций и будем долбить все в стиле С.
При этом, правда, приводятся примеры с использованием тормознеших sprintf-ов, ну, да сути дела это не меняет.
Итог один — формирование стойкой неприязни к абстракциям в следствии погони за битами.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, GlebZ, Вы писали:
GZ>>>>Влад. Только не надо говорить что все программирование ограничивается бизнес-приложениями. VD>>>Я где-то такое говорил? GZ>>Ты такое недвусмысленно подразумевал. VD>Телепат?
Нее, телепузик.
Просто не все есть программы для IBM PС для OS MS Windows. Я в свое время поигрался с эмуляторами технических процессоров. Там такие-же подходы какие мы применяем для бизнес-приложений не подходят. Там приходится всегда думать не об абстракциях, а о системе команд и строении памяти. А этих тварей много, и ведь кто-то их программирует.
VD>>>Одно дело знать, что такое блок памяти, а другое думать только ими. GZ>>Неее. Я до сих пор думаю ими. VD>Слабо верится.
Верь. Тут есть и плюс и минус. С одной стороны не плодю заранее оптимальный код(не путать с дизайном). С другой стороны иногда действительно обидно что приходится писать неоптимальный код(ради дизайна). Переживаю.
GZ>>И это мне помогает понять язык. И тебе тоже. VD>И как тебе помогает понять скажем идиому интерфейсов раздумья о блоках памяти? Ну, или как это тебе помогает понимать паттерны проектирования вроде Посетителя?
Дизайн — это одно. А вот циклы и рекурсии — это другое.
GZ>> А особенно помогает работать с массивами. И смотреть чтобы не было копирования больших данных. И тут абстракция не поможет. Здесь нужно иметь привычку делать так, чтобы потом кардинально не переделывать. Это в большей степени не проблема дизайна, а алгоритмическая проблема. Хотя меру тоже надо знать. VD>Я такой проблемы вообще не встречал. По-моему, и так понятно, что чем больше данных ты бестолку копируешь, тем болше времени и памти таратися зря.
Именно. А еще неплохо бы учитывать что-это стек или динамическая память. И количество циклов. И StringBuild и string в C#. И аллокация в STL. Это не должно отражаться в дизайне. Но на непосредственном уровне самого формирования кода — по-моему вещь достаточно важная.
GZ>>Мы с тобой(судя по возрасту) плоды такого обучения. И я рад что прошел школу 286 процессора и CGA экрана. VD>От части, да. И мне стоило не малых усилий бороться с этими комплексами. Не раз ловил себя на мысли, что нехочу использовать виртуальный вызов просто потому что он медленее обычного. Причем с точки зрения дизайна отказ от виртауального вызова приводил к серьезному усложнению. VD> Это смешно, но мне пришлось провести не один эксперемент чтобы осознать, что стоимость даже самого медленного виртуального вызова — это наносекунды, и что бы от него получить зримое замедление его нужно запихнуть в очень объемный цикл. Если же меня учили сначала создавать грамотный дизайн приложения, а потом уже оптимизировать по-необходимости, то таких проблем никогда не вознило бы.
После определенного момента — меня греет мысль о суперумном компиляторе. Поэтому о виртуальных вызовах вообще не задумываюсь. Но во многих случаях, как уже писал, точно также.
А насчет учебы, так получилось что я самоучка. Меня никто не учил. Все познавал сам. VD>Так вот я осознанно предалел (и продолжаю преодалевать) психологические проблемы борьбы за производительность.
Аналогично. VD>А некоторые товарищи даже не задумываются над необходимостью делать это. И то что эти товарищи старше лет на 10 нисколько их не оправдывает.
Иногда в некоторых задачах это действительно важно. Особенно связанных с математикой. Я когда-то работал на науку, потому знаю. Для большинства бизнес-приложений это действительно неважно. Для McSeem2, я думаю, это и сейчас актуально.
GZ>> Очень обучает думать. Так кто там мерял скорость GDI+? VD>Ничего. Я потом опубликую результаты измерений и боюсь многие будут удивлены в какие мифы они верили. Забегая вперед скажу, что GDI+ не так тормозна как его многие описывают. При грамотном применении эта библиотека на сильно медленнее чем GDI.
А при грамотном граф. процессоре еще менее тормозная? И похоже время достойных процессоров пришло. Новая революция прокралась незаметно. Ура товарищи!!!! Я угадал?
GZ>>Правильно действовать легко научить. Правильно думать — значительно труднее. И для системы алгоритм+доступные_ресурсы — нужно учиться думать. VD>Я не вижу потуги думать у учителя. И почти уверен, что именно этому в превую очередь научатся его ученики. Они всю жизнь будут вызимать биты из байтов. Ведь сломать привычку не так то просто. Любой кто бросал курить или переучивался печатать вслепую поймет о чем речь. VD>Я вижу, что товарищь учитель просто приципиально нежелает думать абстракциями так как они зачастую привносят накладные расходы. VD>Ведь езжу понятно, что быстрее выделения памяти в стэке быть ничего не может. Но это ведь не приводит разумных программистов к отказу от использования тех же строковых классов? VD>Я вижу следующую цепочку рассуждений. VD>Программы жрут больше ресурсов чем могли бы... VD>Надо писать так чтобы использовать минимально достаточный объем ресусров... VD>Абстракции зачастую увеличивают объем используемых ресуросв... VD>Так откажемся от абстаркций и будем долбить все в стиле С. VD>При этом, правда, приводятся примеры с использованием тормознеших sprintf-ов, ну, да сути дела это не меняет. VD>Итог один — формирование стойкой неприязни к абстракциям в следствии погони за битами.
[imho]
Нет. Давай так. Павел привел действительно верные факты если брать алгоритмы программ. После этого — он перенес выводы на уровень архитектуры. Выводы в данном контексте становятся неверны. Как бы человек давно не работает на фронтах бизнес-приложений. Ему высказали все что думали. Но тут и ты начал абсолютно верные факты для дизайна программ переносить на алгоритмы(точнее даже, не учитывать их). И теперь твои факты становятся неверными.
Здравствуйте, Дарней, Вы писали:
Д>это как раз не "сырые" данные — ни один сервер БД не хранит данные в ASCIIZ
Как он хранит — не мое дело. А вот возвращает он из без длины.
PD>>Давай простой пример, искусственный, конечно. Есть огромный файл (1GB , в нем одна текстовая строка, в конце ее , конечно, 0D0A . Я открываю этот файл, делаю на него MMF, позиционируюсь в конец файла, заменяю 0D на 0, имею таким образом строку ASCIIZ. Обрати внимание — файл я не читал. Все — у меня char* pString готов.
Д>а потом понадобилось добавить один символ к концу этой строки, и для этого тебе придется прочитать весь этот гигабайт в поисках маркера конца. Причем — перечитывать полностью каждый раз, как тебе понадобится добавить еще одну строку к его концу. Д>Хороший пример ты привел, ничего не скажешь.
Бог с тобой, зачем же ? Ты вообще с MMF знаком ? Там прямой доступ. Если уж мне надо расширить файл, то я просто создам мэппинг на размер, больший, чем текущий размер файла на требуемую величину. После чего возьму указатель, возвращаемый MapViewOfFile, приведу его к char*, добавлю к нему длину файла, получу указатель на конец данных, добавлю там что надо. Остается только закрыть мэппинг , для фала вызвать SetFilePointer и SetEndOfFile. Все. Исходный файл так и остался непросмотренным.
А даже и без MMF можно. Открываем файл, SetFilePointer на конец-1 (эта операция не читает файл), дописываем данные, закрываем файл. Все.
PD>>Да ведь во входном мире ничего другого нет. Есть некий входной массив байт (из файла, из сети, ...). Этот набор нам дают и все. И чем-то заканчивают, чтобы знали, когда остановиться. PD>>gets банальный, например. А дальше уж наше дело — то ли string из него соорудить, длину мимоходом посчитав и время потратив, то ли не считать длину, отложить до того момента, когда понадобится (может, и не понадобится) . Кстати, в моем примере с конкатенацией я эту длину мог мимоходом вычислить.
Д>не во входном мире, а в той библиотеке, которой ты пользуешься
Библотека откуда данные получает ? Не из входного мира ли ? ИМХО кроме как из входного мира данные брать вообще неоткуда . А вот чтобы из входного мира строки с длиной подавали — как правило, так не делают. А если даже и сделают, это тебе не поможет в случае со string — все равно констуктор string будет исходную строку просматривать и ноль искать. По крайней мере пока это string из STL, а не что-то в Паскале, Перле и т.д.
>>>Читал историю про маляра Шлемиэля?
PD>>Нет.
Д>http://russian.joelonsoftware.com/Articles/BacktoBasics.html
Д>не наводит на размышления?
Да в общем-то ничего интересного. По крайней мере ничего нового для себя я не нашел. Довольно наивные рассуждения, особенно забавно вот это
>Строка не может содержать нулевые байты. Так что хранить произвольные двоичные данные вроде картинки в формате JPEG в строке нельзя.
Между прочим, JPEG очень неудобно хранить так же в виде стека, линейного списка, двоичного дерева и т.д. И не надо — не предназначены эти структуры для хранения JPEG . Как и строка. Кстати, ты готов хранить JPEG в виде string ?
Здравствуйте, Pavel Dvorkin, Вы писали: PD>Код, который читает данные из базы, длину не вычисляет.
Еще как вычисляет. Неудачный пример. PD> Нет такого в SQL SELECT, к примеру. Внутри себя этот SELECT на сервере я не знаю что делает, но мне на клиент в итоге строка попадает как последовательность ASCIIZ.
Неправда. Строка попадает в довольно сложном виде. Никаким ASCIIZ там и не пахнет — приезжает и длина, и признак null, а то еще и кодировка. PD>Последовательность ASCIIZ — "сырые" данные, откуда они взялись — не важно.
Нет уж позвольте. Мне вот очень интересно — откуда взялись эти сырые данные, и почему у них отобрали длину. PD>А в объекте string на входе конструктора эти же сырые данные (а как ты еще string сконструируешь, если не по ASCIIZ или по другому string ?)
Как это? Миллион способов сконструировать строку есть. PD>, а вот в полученном объекте — уже с длиной. Т.е. длину при создании экземпляра string вычислили.
Все верно. PD>Да ведь во входном мире ничего другого нет. Есть некий входной массив байт (из файла, из сети, ...).
Неправда. Это какой-то не тот мир, который я знаю. Файлы уже лет тридцать как снабжаются длиной. Совершенно незачем выполнять последовательное сканирование для ее определения. Я понимаю, что трудно заставить в это поверить человека, привыкшего работать с магнитной лентой, но это так PD>Этот набор нам дают и все. И чем-то заканчивают, чтобы знали, когда остановиться.
В 21 веке пора привыкать к тому, что строка в 99.9999% обладает длиной. И потерять эту длину можно только отрезав ее в одном месте. Чтобы тут же начать вычислять ее в другом. PD>gets банальный, например. А дальше уж наше дело — то ли string из него соорудить, длину мимоходом посчитав и время потратив, то ли не считать длину, отложить до того момента, когда понадобится (может, и не понадобится) . Кстати, в моем примере с конкатенацией я эту длину мог мимоходом вычислить.
>>Читал историю про маляра Шлемиэля? PD>Нет.
Очень, очень напрасно. Вот здесь.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
VladD2 wrote:
> C>Следующий Оффис управляемым не будет, а что будет через 5 лет для меня > C>пока не так важно — все успеет не раз поменяться. > Это и поменяется.
С чего бы? В бэтах Висты .NET играет роль пятого колеса, в Mac OS X (до
которой Винде еще долго расти) управляемый код тоже далеко не главная часть.
Инфраструкту COM на .NET так нормально к Виста перенести и не смогли, а
до следующей итерации пройдет немало времени.
> Но думаю еще до этого сильно поменяется мнение о возможностях > управляемого кода. Сейчас даже в Сан готовят революцию, а уж МС > запрягла такое количество научных учереждений, что у меня сомнений не > возникает.
Вы не ловите момент: сейчас .NET и Java — это уже вчерашний день.
Будущее за AJAX
Здравствуйте, VladD2, Вы писали:
VD>Современные программы состоят из кучи (обычно сотни, а то и тысячи) едениц компиляции (читай файлов). В грамотно спроектированных языках такие еденицы содержат довльно независимые еденицы программы, например, классы. Распараллелить их парсинг не проблема. Прочто создаем такое количество экземпляров парсеров сколько есть физический ядер процессора и в перед...
А если еще вспомнить об алгоритмах вроде GLR, которые параллелятся по своей природе ... Да и для простых LL(1) тоже кой чего в этом плане придумать можно. Например лексер работать в другом потоке с забеганием вперед в то время, когда парсер занят отработкой сложных правил. Или оптимизатор может часть подготовительной работы выполнять еще при парсинге.
GN>> Тут нужно, что бы язык на уровне синтаксиса не давал создавать такие проблемы. То есть, для старых языков не годится.
VD>Это да. Но на то они и старые чтобы или мутировать, или отмерать.
Функциональные языки, кстати, и здесь рулят
VD>SSE — это как бы специализированные подпрограммы реализованные на аппоратном уровне.
Конечно же нет. SSE выполняет специальных блок процессора, по сути векторный сопроцессор, аналог маковского AltiVec. Подробнее http://en.wikipedia.org/wiki/SIMD
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Sinclair, Вы писали:
S>>Здравствуйте, Pavel Dvorkin, Вы писали:
S>>
S>>int GetWindowText(
S>> HWND hWnd,
S>> LPTSTR lpString,
S>> int nMaxCount
S>>);
S>>Return Values
S>>The length, in characters, of the copied string, not including the terminating null character
S>>
PD>>>Есть, в общем, длина. Только от этого не легче — чтобы из этой ASCIIZ строки получить string, придется его конструктор вызывать, string(char*), а он эту строку к себе скопирует (и правильно, конечно, сделает) и длину пристроит. S>>Ну, здесь я ниче не понимаю. Я вижу, что из едита строка приезжает с длиной.
PD>Все верно, кто же спорит. Но возвращают строку отдельно, а длину отдельно. Вот если бы эта функция string STL вернула, другой разговор был бы. А так — придется этот, между прочим, char* буфер, передать string констуктору, который эту длину перевычислит. PD>Так что возвращает edit длину или нет — с точки зрения конструирования string не имеет значения.
std::string имеет конструктор, принимающий два итератора. Передаёшь в него указатели на начало и конец строки и никакого перевычисления длины не происходит. А ещё есть конструктор, который передаётся указатель на начало и длина.
Так что имеем здесь нормальное копирование входной строки. Длина, правда, берется не из нее, поскольку в документации сказано, что
pch
A pointer to an array of characters of length nLength, not null-terminated.
Просто еще один конструктор у класса есть, вот и все. Можно и другие придумать, если угодно. От этого ничего не меняется. И строка там опять-таки хранится с завершающим нулем.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>А если использовать StringBuilder, то ведь потом нужно копировать в string и в итоге 2 прохода все же ? S>Нет. Там в большинстве случаев никакого копирования нету. UTSL, т.е. Reflector. S>Код, который я привел, должен приводить к практически идеальному результату. Можно потестировать, что быстрее — подсчитывать суммарную длину или нет — в зависимости от количества строк в IEnumerable. Но это в любом случае эффекты второго порядка малости.
Посмотрел я на это дело рефлектором, чуда, естественно, не произошло, получится два прохода:
S>Я тебе показал то место, откуда можно взять сразу готовый объект строки без пересчета длины. Покажи мне теперь то место в винапи, где есть только char*, а длины нету. Не бойся — оно есть
Все, извини, но это письмо будет точно последним. Времени больше на эти дискуссии нет — увы, заказчик прислал наконец спецификации проекта, и он именно на С# .
Могу сделать тебе относительный комплимент — дискутировать ты умеешь. К сожалению, вынужден также отметить и твои , увы, не совсем корректные способы дискуссии типа ухода от вопросов, которые тебе не нравятся или подмену сути вопроса. Я это заметил не сразу.
Впрочем, это не так уж важно — все равно вся эта дискуссия ни к чему. В конце концов чего мы ей добиваемся на потеху всей публике ? Доказать друг другу мы ничего не сможем, это давно ясно. Еще один набор аргументов с моей или твоей стороны — ничего не изменит. Так что я заканчиваю.
//оптимально по производительности
int cnt=GetCount();
....
for(int i=0;i<cnt;i++){...}
....
for(int j=0;j<cnt;j++){...}
//оптимально по дизайну
for(int i=0;i<GetCount();i++){....}
.......
for (int j=0;j<GetCount();j++){....}
А если так:
for(int i=0, cnt=GetCount();i<cnt;i++){....}
.......
for (int j=0, cnt=GetCount();j<сnt;j++){....}
Здравствуйте, Alexey Axyonov, Вы писали:
VD>>Это старый АПИ. Оно не будет работать на машинах с новым вордом. По крайней мере на моей машине где стоит Word 2003 оно не работает.
AA>Влад может на счет АПИ ты и прав, но у меня Word 2003 SP2 и оно работает.
В SP2 похоже многие глюки пофиксили. Может услышали как я разоряюсь?
Но SP2 появился только сейчас. А Ворду уже много лет и как минимум 10 из них он содержал в себе один и те же глюки.
Кстати, точно сказать, что глюки пофиксили пока не могу, так как времени прошло немного с выхода SP2. Но через месяцок другой скажу.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, eao197, Вы писали:
E>Вот и спросили товарища: "Дайте определение оптимальной функции!"... Хорошо еще, что все хорошо закончилось.
E>Может давай я тебе еще пару примеров приведу к тому, что Павел у себя указал?
E>Вот берем браузер Opera. В нем еще и RSS-ридер есть, и почтовый клиент. И поиск по почте/сообщениям за доли секунды выполняется. И сам браузер 3.5Mb в дистрибутиве занимает (без Java). И памяти при работе у меня сейчас 44Mb занимает с 14-ю открытыми табами. Кому как, а по мне Opera весьма эффективная программа.
У меня впечатления строго наоборот. Была опера, правда старая(не помню версию, по моему 6). Строго отжирала 100мБ в лучшие дни. В худшие еще больше. Поэтому с Оперой, у меня строго обратные ассоциации.
Слушай, а сколько мег у тебя занимает база сообщений?
mrozov wrote
> Необходимость в написании ну о-о-о-очень эффективных программ отпала. > И слава богу. Туда и дорога. > Потому что единственными, кто был в этом заинтересован, были сами > компьютерные энтузиасты (вроде вас, автор?), которые предпочитали ... > э-э-э-э заниматься с компьютером любовью непременно стоя и непременно > в гамаке. > А почти полная утеря общественностью навыков эффективного создания > каменных топоров вас не волнует? А врдруг железо закончится, что > делать будем? > Индустрия променяла эффективность кода на эффективность труда. И на > его облегчение. Что тут плохого?
Ошибаетесь, вот МС показала здравый смысл — в Windows Vista все как и
раньше будет основано на unmanaged-приложениях. В том числе и explorer с
оффисом. И пока программисты, ратующие за увеличение производительности
труда, будут писать чего-то там на WinForms или Avalon'е — МС будет
совершенствовать свой набор оффисных программ, интегрированных через
OLE2 (аналога которого в managed-мире нет и не предвидится).
Здравствуйте, GlebZ, Вы писали:
E>>Вот берем браузер Opera. В нем еще и RSS-ридер есть, и почтовый клиент. И поиск по почте/сообщениям за доли секунды выполняется. И сам браузер 3.5Mb в дистрибутиве занимает (без Java). И памяти при работе у меня сейчас 44Mb занимает с 14-ю открытыми табами. Кому как, а по мне Opera весьма эффективная программа. GZ>У меня впечатления строго наоборот. Была опера, правда старая(не помню версию, по моему 6). Строго отжирала 100мБ в лучшие дни. В худшие еще больше. Поэтому с Оперой, у меня строго обратные ассоциации.
Ну, 7-ка и 8-ка весьма экономичные. А 6-ку я уже и не помню.
GZ>Слушай, а сколько мег у тебя занимает база сообщений?
~252Mb.
Но у меня еще и года использования Janus не прошло, да и подписан я всего на 7 форумов.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Cyberax, Вы писали:
C>Ошибаетесь, вот МС показала здравый смысл — в Windows Vista все как и C>раньше будет основано на unmanaged-приложениях. В том числе и explorer с C>оффисом. И пока программисты, ратующие за увеличение производительности C>труда, будут писать чего-то там на WinForms или Avalon'е — МС будет C>совершенствовать свой набор оффисных программ, интегрированных через C>OLE2 (аналога которого в managed-мире нет и не предвидится).
Маленько ошибочка вышла. Поддержка офисом Net'а уже давно есть. Даже и без нее можно работать Com'ом. OLE2 давно умерла, остались ActiveX. Поддержка его(кривая правда) но все таки есть.
GlebZ wrote:
> C>Ошибаетесь, вот МС показала здравый смысл — в Windows Vista все как и > C>раньше будет основано на unmanaged-приложениях. В том числе и > explorer с > C>оффисом. И пока программисты, ратующие за увеличение производительности > C>труда, будут писать чего-то там на WinForms или Avalon'е — МС будет > C>совершенствовать свой набор оффисных программ, интегрированных через > C>OLE2 (аналога которого в managed-мире нет и не предвидится). > Маленько ошибочка вышла. Поддержка офисом Net'а уже давно есть.
Я сказал "основана" — .NET в том же Word'е играет только роль
скриптового языка.
> Даже и без нее можно работать Com'ом. OLE2 давно умерла, остались > ActiveX. Поддержка его(кривая правда) но все таки есть.
OLE2 — живее всех живых (см. оффис). ActiveX — это примерно subset
технологий OLE2.
mrozov wrote:
> Причины непереписывания на .net word-а по-моему очевидны. К > неэффективности .net никакого отношения они не имеют.
Да ну?
> И вообще — я бы поставил вопрос иначе — пока ратующие за эффективность > кода будут ковыряться в своем низкоуровневом коде, использующие > windows forms (или VB) коллеги будут успешно сдавать заказчику один > проект за другим.
Ну да, и через год об этих проектах забудут. А вот выверенные и быстрые
низкоуровневые приложения будут продаваться и развиваться еще долго.
> Когда руководитель группы разработки этой фирмы во время сравнительных > испытаний возможностей их системы и того, что было сделано тремя > нашими разработчиками за пол-года, увидел наш вариант — у него > натурально дрожжали руки. У человека началась форменная истерика — > потому что от очень четко понял свое место в этой жизни. И место > своего подхода к разработке ПО, соответственно.
Ну значит плохо на С++ писали. У нас была обратная ситуация — группа
С#истов полтора года делала приложение. Оно у них работало, но медленно
и не особо устойчиво (подумаешь, пара исключений при запске — ничего
ведь не падает).
Поэтому когда мы выкатили заказчику примерно такой же продукт с
поддержкой OLE2 (то есть наши документы можно, например, в Word
вставлять) — старое приложение торжественно удалили.
Здравствуйте, Cyberax, Вы писали:
C>OLE2 — живее всех живых (см. оффис). ActiveX — это примерно subset C>технологий OLE2.
И да, и нет. Насколько я помню, в ActiveX уменьшили количество обязательных интерфейсов. И добавили свои. Но OLE2 он не отрицал. Он его развивал.
ie>Действительно, мы сейчас живем в век дешевой техники и дорогой рабочей силы. Но экономя на поддержке и разработке многие, прежде всего заказчики и начальники, действительно портят программистов. Что однако не умоляет множество глупых и бездарных программ.
Это не заказчики и начальники. Многие из них и не знают каким образом вся эта груда текста, написанное на языке очень похожем на английском, может работать. Разработка — это дело самих разработчиков. И поставить например Code Review — это не работа заказчика, это работа разработчиков. Так что винить надо только себя.
ie>Вот с архитектором в проекте очень даже повезло. Сейчас используется 5 ЯП с соответсвующими им технологиями. Я бы еще пол года назад сказал бы — да зачем мне какой-то там Питон, .NET форева. (Надеюсь больше меня эти мысли посещать не будут.) Все от начала до конца можно было сделать на .NET. Однако, прилили и C++, и Питон, и Ява Скритп, и Перл. Чего добились — думали: путаницы и неразберихи — оказалось: простоты и эффективноти!
А вот это плохо. Смешивать питон с перлом. Будь моя воля, я бы привел все к одному языку. Очень трудно переключаться с одного языка на другой. Вроде бы очень похоже, и термины такие-же. Только дизайн программ весьма зависит от используемого языка. Есть языки которые от которых зависят выбранные технологии. Тут хочешь не хочешь надо. И это хорошо. Но если что-то можно сделать одним языком, то это нужно делать именно этим языком.
С чего все началось. Началось с того, что к Net программам Павел начал приставлять свойства C++. Ну нет у него многих свойств С++. Точно также и нет многих свойств C# у С++. В результате, дизайн программ существенно различается. По форуму Net очень часто поступают вопросы, сквозь которого проступает C++.
И данный пост Павла(которым он наконец разродился) именно связан с темой сравнения с С++.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD> Создается впечатление, что рост быстродействия процессоров несколько PD>замедлился. Может быть, я не прав, но мне кажется, что мы подошли к некоторому PD>пределу, и если не последует технологического прорыва, то скорость сильно расти PD>не будет. Еще раз — может быть, я не прав. Кстати, о памяти пока в этом плане PD>говорить не приходится.
PD> Но так или иначе — этот предел есть. Очень уж четкие физические PD>законы здесь действуют, их не обойдешь. Раньше или позже, но бурный рост PD>мощности ПК заменится если не стагнацией, то более или менее плавным изменением, PD>на проценты, а не в разы.
Абсолютно верно. Мы уже подошли к пределу. У меня 3GHz процессор уже два года. И никакого двухкратного скачка частоты за 18 месяцев не предвидется.
Тем не менее плотность транзисторов можно наращивать и дальше. Поэтому процессорная индустрия переходит из области гонки за частоту в область много ядерных процессоров (multicore). Уже существуют dual-core Intel Pentium D & AMD Athlon64 X2. В скором будущем у нас будут гораздо больше core, порядка десяти.
Здравствуйте, Dyoma, Вы писали:
D>А как вам вот такой тезис, что программа просто должна быть достаточно xxx? D>Не надо выделять потребляемую память и быстродействие в отдельную категорию. Программа должна быть достаточно во всем и, в идеале, одинакого. Далее неупорядоченный список: достаточно функциональна; достаточно удобна; достаточно устойчива; достаточно мало жрать память; достаточно быстро работать;
Если бы мы были в однопрограммной системе — готов согласиться. А в многопрограммной — нет. Потому как отдельная программа может быть вполне достаточна, а все вместе они едят ресурсов немеряно и тормозят.
Кстати, сформулируй критерий достаточности, если можешь.
D>Я ни в коем случае не призываю не думать об эффективности, не искать всегда и везде лучшие подходы и алгоритмы. Я предлагаю не думать об этом больше/чаще, чем о, например, удобстве UI или чистоте и последовательности архитектуры.
Удобство UI прямого отношения к эффективности обычно не имеет. А вот чистота и последовательность архитектуры отнюдь не требует применения неэффективных методов. Скорее наоборот — скажи кратко, но хорошо (К. Прутков)
Ответили мне многие. Всем спасибо за обсуждение. К сожалению, не могу ответить всем, да это и не надо, пусть дискуссия идет своим чередом.
Но вот одно либо я недостаточно четко изложил, либо меня не поняли, либо не хотели понять. Я не призыаваю к тотальной оптимизации, это просто глупо, в конце концов. И те, кто меня в этом упрекают, зря стучатся в открытую дверь. Я выступаю за то, чтобы код на своем уровне писался эффективно. Чтобы не использовались явно избыточные по памяти или времени конструкции, когда это совсем не обязательно и вполне ясно, как без них обойтись, отнюдь не поступаясь при этом ясностью и четкостью.
И если интструмент спроектирован так, что он мне неизбыточное кодирование делать не дает, а заставляет или хотя бы толкает на это избыточное исходя из того, что нечего эти ресурсы экономить — вот с этим я и не согласен.
Не, ну по поводу word-а все как раз очевидно. Там уже столько всего наколбашено и до такой степени криво, что что-либо переделовать по большому счету они сами боятся. Да и нужды нет.
А вообще — мы говорим о немного разных вещах. Есть время и место для низкоуровневых технологий. Так же, как есть время и место для оптимизации.
И то и другое (по моим представлениям) состовляет ну никак не больше 10% от всех нужд.
И как бы "хардкорщикам" не хотелось обратного, но большая часть рынка и большая часть программистов — это прикладники. Т.е. ваши аргументы просто пролитают мимо меня со скоростью пули."Вот мы писали драйвер и Java оказалась слабовата". Ну да. И что?
Здравствуйте, gear nuke, Вы писали:
GN>2 ядра — та ещё "конфетка". Ни о каком увиличении скорости в 2 раза речи быть не может. Общая шина памяти, необходимость в когеррентности данных в кеше — это только низкоуровневые железнае проблемы. Когда будет 8 ядер все эти заморочки только усугубятся. Эффективных способов решения нет, и, боюсь, не будет.
О чём я и говорю. Dual-core с точки зрения программы — это два процессора. Если программа однопоточна, как большинство существующих, то никакого увеличения производительности не будет. Однако, если мы научимся писать многопоточные программы, то есть шанс, что их производительность будет расти с ростом количества ядер. Есть, конечно, проблемы с памятью, но я думаю, что производительность памяти будет еще некоторое время расти, и память будет становиться дешевле.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Но вот одно либо я недостаточно четко изложил, либо меня не поняли, либо не хотели понять. Я не призыаваю к тотальной оптимизации, это просто глупо, в конце концов. И те, кто меня в этом упрекают, зря стучатся в открытую дверь. Я выступаю за то, чтобы код на своем уровне писался эффективно. Чтобы не использовались явно избыточные по памяти или времени конструкции, когда это совсем не обязательно и вполне ясно, как без них обойтись, отнюдь не поступаясь при этом ясностью и четкостью.
GN>2 ядра — та ещё "конфетка". Ни о каком увиличении скорости в 2 раза речи быть не может.
Ага. И есть даже закон. здесь GN>Общая шина памяти, необходимость в когеррентности данных в кеше — это только низкоуровневые железнае проблемы. GN>Когда будет 8 ядер все эти заморочки только усугубятся. Эффективных способов решения нет, и, боюсь, не будет.
В архитектуре Фон Неймана, да. Усугубляться. А насчет 8 ядер — посмотри Cell. здесь
Здравствуйте, ie, Вы писали:
ie>Ну не скажи.... Живой пример. Я попросил своего менеджера ежедневно выделять из моего рабочего времени 1 час на ревью кода вновь пришедшего. Ну не умеет новенький эффективный код писать и это не его вина, не научили еще. Нет же, и так в сроки можем не уложиться. Сдадим этап, тогда если(!) сильно тормозить будет, возможно(!), сделаем ревью... Вот так — если и возможно! А так — работает и пес с ней с эффективностью. Вот кто виноват? Скажи, пожалуйста.
Значит аргументация подкачала. На войне больше всего боялись даже не немцев. Больше всего боялись плохого командира. ie>В итоге — пора сдавать, а DataGrid ну уж очень тупит при отрисовке. Студент делал его раскрасску. Хочешь расскажу какой он код в DataGridColumnStyle.Paint напихал
Обычно это в юмор, ветка про индусов.
ie>Смотря что понимать под "смешивать". Если я не ошибаюсь Перл пришел из-за необходимости генерить Excel отчеты (могу ошибаться, сам в Перловую часть не разу не лазил). Ну нет в .NET средств эффективной генерации Excel отчетов. В Perl есть, взяли, прикрутили. Почему это плохо?
Вообще-то в Net много чего есть. Можно и отчеты генерить. Непонимаю. ie>Лично мне, да никому другому, не надо переключаться между всеми 5ю языками.
А мне приходится. Сразу понимаешь недостатки того или иного языка. Например, нечитабельность C++(когда работал на чистом С++, таких проблем не ощущал). Или отсутвие автоматических деструкторов в Delphi. Про разность методов работы, я уже писал.
ie>Ну вот тот же пример с тестом Павла. Он явно дает понять, что ++ код эффективней справляется с поставленной задачей. Так и сделать эту чать на ++, конечно, без фанатизма, если эта часть действительно критичная, а не бегать каждый раз делать на ++ все что там даст выйгрыш в скорости и использовании памяти.
В конкретном случае, да. Но без ясной и понятной причины, этого делать нельзя.
GZ>>С чего все началось. Началось с того, что к Net программам Павел начал приставлять свойства C++. Ну нет у него многих свойств С++. Точно также и нет многих свойств C# у С++. В результате, дизайн программ существенно различается. По форуму Net очень часто поступают вопросы, сквозь которого проступает C++. GZ>>И данный пост Павла(которым он наконец разродился) именно связан с темой сравнения с С++.
ie>Да, и это не может не огорчать. Вместо того чтоб спорить что же все таки лучше, общими усилиями написали бы статью, о том какие классы задач и их подзадач с помощью какой технологии эффективно решаются.
Пройди по поиску. Это не раз обсуждалось.
GlebZ wrote:
> PD>Чудно. А могу я эти сервисы безболезненно удалить, и освободить > Мбайт так 50-60 ? Немного — получится, а остальные, увы, обязательны > для системы. А мне, в общем, все равно, как это называется, ядро или > сервисы, лишь бы занимали они поменьше. > Тут конечно фигня творится. Когда новую функциональность с > исправлением ошибок смешивают. Но отрицать то, что увеличение > функциональности сервиспаками и требования к памяти строго > пропорциональны, нельзя. Таже NT4 — с последними сервис паками мег 100 > занимает оперативы.
Это, наверное, если все сервисы сразу запустить. Я долгое время без
проблем работал на P166+32Mb+NT SP6.
McSeem2 wrote:
> А вот слова Matthew MacLaurin из Microsoft MSX group, который зовет > меня туда работать: > The project is an advanced, small-team product – an information > manager for the internet age. We started it in research and are now > going to ship it. It uses queries as the primary organizational > construct – letting users easily build and manipulate queries as first > class objects, etc. It also emphasizes tagging and distributed > information. We’ve put a lot of work into a very elegant and polished > user interface with translucency, drop shadows, seamless compositing > everywhere, etc. *Our prototype is up and running in C#, and we are > now porting to C++*. > К чему бы это?
Кстати, у нас в постановке проекта так и звучало: "Переделать прототип
приложения c C# на С++" Между строчками читалось: "Эта <пиииииии>
программа на C# не может делать ни <пииииииииии>. Сделайте нам нормальную."
Здравствуйте, Nickolay Ch, Вы писали:
NC>Уважаемый mrozov правильно написал, что времена любителей позаниматься сексом с компом прошли в индустрии программирования. Энтузиастам и "вольным художникам" не место в индустрии.
Вот это сильно сказано.
Пора менять профессию.
NC>Все вышенаписанное — мое имхо.
На это и остается расчитывать. А вдруг ты прав?
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А во-вторых, опять же не туда показываешь. Я об общем стиле написания говорю, о заведомо неэффективных конструкциях, которые порой используются. В определенных случаях это может не сказаться, согласен. А вот когда весь код таким образом пишут, то повышается общий уровень неэффективности.
Люди никак не могут научиться писать программы, которые хотя бы работают без багов. А ты еще хочешь взвалить на них задачу по "повышению общей эффективности"
Догадываешься, к чему это приведет? (только не надо тоже рассказывать, что УЖ ТВОИ программы никогда не глючат — все равно не поверю )
Повышение "общей эффективности" — это задача компилятора и исполняющей среды. Пусть даже они сейчас работают не так хорошо, как надо бы.
Так что если тебя так сильно заботит эта тема — займись лучше разработкой соответствующих средств для автоматической оптимизации, вместо того чтобы заниматься здесь ерундой
PD>Перекодирование строки из файла из 866 в 1251.
PD>Все что я нашел, сводится к
PD>public string MyDecoder(string str) PD>{ PD> byte[] b = Encoding.GetEncoding(866).GetBytes(str); PD> str = Encoding.GetEncoding(1251).GetString(b); PD> return str; PD>}
PD>или вариациям на эту тему
Есть еще Encoding.Convert
Может быть, он поможет отцу российской демократии?
PD>Я вполне допускаю, что ты сейчас мне это эффективнее напишешь. Ты. А все будут именно это и делать.
Ну и пусть делают. Я лучше буду иметь дело с неэффективной, но работающей реализацией. Чем с дьявольски эффективной, но ни хрена не работающей
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Nickolay Ch, Вы писали:
NC>>Буду краток: писать код надо так, чтобы из него можно было получить максимальную денежную прибыль. NC>>Энтузиастам и "вольным художникам" не место в индустрии. C>Именно поэтому на моем винчестере остается все меньше программ, которые делались для получения максимальной денежной выгоды. Так как программы, написаные энтузиастами и вольными художниками все чаще становятся лучше коммерческих собратьев.
Не согласен. Никакого "чаще" не наблюдается. И предлагаю тут не спорить, ты используешь одни программы, кто-то другие. Я, к примеру, юзаю проги по большей части от МС. И меня они очень даже устраивают. На вкус как известно...
C>Хорошие коммерческие продукты, которые я использую, НЕ живут по правилу "максимальной денежной прибыли", а по правилу "Делать все, чтобы пользователям было удобно — тогда и прибыль будет".
Далеко не все пользователи, а тем более корпоративные заказчики такие как ты Но не в этом суть. Как всегда, человек читает не то что написанно, а то, что хочет прочесть.
Вообще то, я хотел сказать, что единственным незыблемым критерием того, как надо производить софт, является то, сколько ты за него получишь. Это не значит что надо писать софт "плохо".(Пусть каждый поймет это слово так как ему приятнее). Из этого отправного пункта и идем — если получим больше за то, что сделаем "чтобы пользователям было удобно"(кстати очень сложный и неформализуемымй момент), то будем делать так.
Получим больше за то, что прога занимает минимум места и летает на 100 пеньке — делаем так.
Получим за то, что сляпаем прогу которая жрет полгига и требует 3ГГц проца, но зато сляпана за неделю при минимальных вложениях — делаем так.
Нужен разнообразный функционал — а времени нет, берем богатый, пусть громоздкий, но уже готовый и отлаженный фреймворк. Все зависит от задачи.
Здравствуйте, Valentin Butakov, Вы писали:
GN>>ИМХО не стоит забывать, что развитие часто идёт по спирали... VB>Это не развитие идет по спирали, это просто отдельные люди любят повторять старые и давно известные ошибки...
Под ошибками понимаются дефекты транзисторов, когда их напичкано больше чем позволяет технология?
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
Здравствуйте, alexeiz, Вы писали:
A>О чём я и говорю. Dual-core с точки зрения программы — это два процессора. Если программа однопоточна, как большинство существующих, то никакого увеличения производительности не будет.
Увеличение производительности будет — в многозадачной ОС намного больше одного thread.
A>Однако, если мы научимся писать многопоточные программы, то есть шанс, что их производительность будет расти с ростом количества ядер.
Научиться мало. Железнае проблемы как обходить? Одному-то процессору мало пропускной способности памяти, а если их больше, то они начинают "мешать" друг другу.
A> Есть, конечно, проблемы с памятью, но я думаю, что производительность памяти будет еще некоторое время расти
Производительность памяти уже давно растёт медленнее производительности ядра CPU. И если внутри кристалов ещё можно что-то делать, то на внешних проводниках всё намного сложнее.
A>и память будет становиться дешевле.
А когда начнут интегрировать RAM в корпус CPU (что бы избавиться от проблем с печатными платами), то как будем добавлять память?
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
Здравствуйте, eao197, Вы писали:
E>Давайте это Ричарду Столлману (GCC, emacs), Линусу Торвальдсу (Linux), Тео да Радту (OpenBSD), Гвидо ван Россому (Python), Ларри Уоллу (Perl), Якиро Матцумото (Ruby), ...(список можно продолжать)..., раcскажем. А то мужики, право слово, фигней страдают. Надо их жизни-то научить.
Вы не совсем правильно поняли. Хотя, возможно я тоже некорректно выразился. Это был всего лишь совет тем кого напрягает текущая ситуация в массовом бизнес-программировании. Обороты его и вправду больше, чем у OSF, и продуктов они выпускают больше (хотя и далеко не факт что лучше, но все же). Open-source движение отчасти противостоит "денежным мешкам" и их методам работы, и действительно эти люди нашли нишу в области ИТ в которой еще можно заниматься более-менее творческим программированием. Я лично только за этих людей и рад этому движению, жаль что оно пока не такое же массовое как и "закрытый софт", поэтому не оно в некоторых вещах определяет, к сожалению, лицо ИТ. Но это вселяет некоторую надежду, что не все еще "потеряно" (хотя я нигде и не говорил что все потеряно). Все они безусловно не "страдают фигней", а занимаются крайне полезными делами и молодцы! Из моих слов никак не следовало, что они не правы или что в программировании больше нет ну совсем уж ничего интересного. Выразился просто слишком уж прямо и эмоционально... Но "закрытое" коммерческое программирование действительно становится больше рутиной, чем творчеством, с этим Вы согласны?
E>Ребята, если вы относитесь к программированию как к обычной работе, средству заработка, то и относитесь себе так и дальше. Зачем же подобные советы давать
[skipped] E>Посмотрите лучше на другие отрасли, которые уже не один век существуют.
Ну хорошо, первый совет был несколько эмоциональный (уйти из программирования). Но второй-то вполне нормальный! Я советовал всем работать хорошо, что в этом плохого?
E>На образование, например. Там что, нет возможности для творчества? А как же учителя, которых потом всю жизнь с благодарностью вспоминают?
А причем здесь это? В ИТ тоже много хороших людей, которых вспоминают с благодарностью. Но "массового" творчества уже почти нигде нет, потому что отрасли уже давно сложились и что-то там новое придумать по сути все тяжелее и тяжелее. Остается небольшая личная инициатива или можно просто хорошо работать к чему я и призываю! А там глядишь и Амосовы и Федоровы из кого-нибудь получатся...
Здравствуйте, pp2, Вы писали:
pp2>Но "закрытое" коммерческое программирование действительно становится больше рутиной, чем творчеством, с этим Вы согласны?
Если речь идет о заказном, оффшорном программировании, где все определяет будущий владелец всего кода, то вполне возможно, что так и есть.
А если компания выпускает собственный коробочный или просто тиражируемый по заказ софт, то совсем не факт.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
).
В догонку — с mrozov я как раз не согласен. Я нигде не говорил что деньги определяют все. Я лишь посетовал, что увы все больше (в массовом коммерческом программировании)... Писать _только ради денег_ — это крайний случай и как любая крайность — не самый лучший выход. Но увы так многие поступают. А я такого совета никогда не давал. Все что я советовал — это действуйте сообразно обстоятельствам и работайте хорошо.
Вот мои слова:
"работу надо стараться делать хорошо, потому что плохо оно само получится."
и еще одни
"Надо писать соответственно текущему уровню развития отрасли."
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, pp2, Вы писали:
pp2>>Но "закрытое" коммерческое программирование действительно становится больше рутиной, чем творчеством, с этим Вы согласны?
E>Если речь идет о заказном, оффшорном программировании, где все определяет будущий владелец всего кода, то вполне возможно, что так и есть. E>А если компания выпускает собственный коробочный или просто тиражируемый по заказ софт, то совсем не факт.
Варианты конечно всегда есть, но даже если софт "свой", и на продажу в конечном счете, то рынок одинаково "безжалостен" ко всем. Как опередить конкурентов? Как предложить больше всяких фич и сэкономить бюджет проекта? Ну и т.д., соответственно "творчество" здесь весьма на любителя. И кстати частично даже не в области программирования вообще.
Если софт открытый или не на продажу — то да, возможны варианты. Хотя общая тенденция на лицо.
Здравствуйте, GlebZ, Вы писали:
GZ>В архитектуре Фон Неймана, да. Усугубляться. А насчет 8 ядер — посмотри Cell.
Я как-то смотрел его (поверхностно). Пришёл к выводу, что маркетологи в очередной раз отрабатывают свои деньги. До "нормальных" CPU ему подрасти бы не мешало, это что-то вроде DSP — эффективно только на узком круге задач. Ну и проблемы с пропускной способностью памяти не решает.
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
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, GlebZ, Вы писали:
GZ>>В архитектуре Фон Неймана, да. Усугубляться. А насчет 8 ядер — посмотри Cell.
GN>Я как-то смотрел его (поверхностно). Пришёл к выводу, что маркетологи в очередной раз отрабатывают свои деньги. До "нормальных" CPU ему подрасти бы не мешало, это что-то вроде DSP — эффективно только на узком круге задач.
Я бы так не сказал. Но есть проблема что при нынешних языках это пока нереально. GN>Ну и проблемы с пропускной способностью памяти не решает.
Обрати внимание на быстрые, прямые, шины между процессорами.
Здравствуйте, GlebZ, Вы писали:
GN>>это что-то вроде DSP — эффективно только на узком круге задач. GZ>Я бы так не сказал. Но есть проблема что при нынешних языках это пока нереально.
ИМХО проблема не в языках. Многие алгоритмы имеют зависимости по данным (нельзя продолжать выполнение, пока не известен результат предыдущей операции). Да возьмём для примера любимый компилятор — даже если распараллелим компиляцию отдельных файлов, то как быть с линкером?
Можно вспомнить много таких "революционных" технологий даже на x86 — MMX, SSE, ... реальных выигрышей они не дают, если бы обычных регистров добавили, да нормальный (не стековый) FPU сделали — результат бы мог и лучше получиться. Но это бы была только *эволюция*.
GN>>Ну и проблемы с пропускной способностью памяти не решает. GZ>Обрати внимание на быстрые, прямые, шины между процессорами.
Ну это для тех, кто решает в какие акции деньги вкладывать .
Меня больше смущают медленные, загогулистые шины CPU <-> RAM. Перед тем, как ядро начнёт что-то там считать на своей мега-скорости, ему нужно что-то прочитать из медленной памяти. И если расширяя шину памяти можно немного поднять скорость, то от латентности никак не избавиться.
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
Здравствуйте, GlebZ, Вы писали:
PD>> Другой пример — сама Windows. Я прекрасно понимаю, что Windows NT 4 и PD>>Windows XP — не совсем одно и то же. Но та на 8 Мбайтах работала, а эта от PD>>128 нос воротит, подавай ей 256. GZ>NT 4.0 на 8 мегабайтах не работала, а обслуживала саму себя. И то, если сервис паки не ставить.
Знатоки блин. У NT 4.0 в минимальных требованиях было записано 16 мег. И как раз в них она осблуживала сама себя. А чтобы еще и в Дельфи на ней можно было работать комфортно нужно было поставить 32 метра.
Когда появились 128 метров стало ясно, что NT 4.0 просто неумеет извлечь выгоду из "такого объема памяти". Тогда появились сервиспаки которые содной стороны позволили NT 4.0 эффективно задействовать бОльший объем памяти, а с другой банально подняли требования к ее объему и были оптимизированными именно ан болИе объемы памяти. ХРюша может запустить на 32 метрах, но оптимизирована она на 256+.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
mrozov,
> Да в чем же я ошибаюсь? Везде, где это возможно, все стараются делать проще, а не эффективнее. > > Причины непереписывания на .net word-а по-моему очевидны. К неэффективности .net никакого отношения они не имеют.
И да, и нет. Если переписать, то, может, оно и нормально будет — сейчас, без эксперимента, сложно наверняка говорить Но вот причина, почему они не выпускают Office, перекомпилировав его с помощью MC++ или C++/CLI, заключается как раз в заметно уменьшающейся производительности, которую показывают собранные таким образом приложения Office.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Pavel Dvorkin,
> Не все сводится к мемори ликам и некорректным индексам. От ошибок алгоритма меня никакой FrameWork не защащает. Складывать килограммы с метрами (вместо того, чтобы умножать) и там вполне можно, .
С такими ошибками в C++ шаблоны могут помочь бороться.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Nickolay Ch,
> Вообще-то особенно при работе в команде код должен быть подчинен стандарту. Суть в том, что основная часть производства софта это именно индустрия, масс-продакшн.
LOL
Это не так хотя бы по простому факту того, что выпускаемые программы отличаются друг от друга. В противном случае не понимаю, зачем их много...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Mikhail Polykovsky,
>>> Вообще-то особенно при работе в команде код должен быть подчинен стандарту. Суть в том, что основная часть производства софта это именно индустрия, масс-продакшн.
> ПК> Это не так хотя бы по простому факту того, что выпускаемые программы отличаются друг от друга. В противном случае не понимаю, зачем их много...
> Диванов тоже много разных. И все произведены серийно.
Разница: программы все разные, а диванов, выпускаемых серийно, много одинаковых. Соответственно, изготовление партий (одинаковых) диванов -- серийное производство, а изготовление (уникальных) диванов/программ -- штучное.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Перекодирование строки из файла из 866 в 1251.
S>Гон. В файле нет строки. В файле есть байты. S>Поэтому достаточно использовать ровно один Encoding.Convert. S>Если ты из файла получил строку, то ты сам виноват — делаешь три Convert вместо одного.
А я тут ни при чем. Я просто привел пример из дискуссии
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Mikhail Polykovsky,
>>>> Вообще-то особенно при работе в команде код должен быть подчинен стандарту. Суть в том, что основная часть производства софта это именно индустрия, масс-продакшн.
>> ПК> Это не так хотя бы по простому факту того, что выпускаемые программы отличаются друг от друга. В противном случае не понимаю, зачем их много...
>> Диванов тоже много разных. И все произведены серийно.
ПК>Разница: программы все разные, а диванов, выпускаемых серийно, много одинаковых. Соответственно, изготовление партий (одинаковых) диванов -- серийное производство, а изготовление (уникальных) диванов/программ -- штучное.
Другой пример — корпусная мебель. Части одинаковые, а шкаф каждому свой нужен. Сборка — отверткой.
Здравствуйте, Sinclair, Вы писали:
>- эффективно, а за S>
S>...(IEnumerable<string> strings)
S>{
S> string s = string.Empty;
S> foreach(string a in strings) s=s+a;
S> return s;
S>}
S>
S>надо бить линейкой.
Sinclair, sorry, а не мог бы ты подсказать, как здесь эффективно сконкатенировать все же массив строк при том, что количество их определится в момент конкатенации? Твой первый пример хорош, но там жестко 3 строки. На C++ конкатенацию массива строк в новую строку (я имею в виду не string из STL, а char*) я все же напишу однопроходным алгоритмом и при этом не будут использоваться никакие промежуточные буферы. Потому что задача по определению однопроходная. Здесь это можно, используя только string, а не StringBuilder ? А если использовать StringBuilder, то ведь потом нужно копировать в string и в итоге 2 прохода все же ?
Mikhail Polykovsky,
> ПК>Разница: программы все разные, а диванов, выпускаемых серийно, много одинаковых. Соответственно, изготовление партий (одинаковых) диванов -- серийное производство, а изготовление (уникальных) диванов/программ -- штучное.
> Другой пример — корпусная мебель. Части одинаковые, а шкаф каждому свой нужен. Сборка — отверткой.
Теперь осталось показать, что при разработке программ процесс происходит более-менее также...
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, VladD2, Вы писали:
VD>ХРюша может запустить на 32 метрах, но оптимизирована она на 256+.
При этом гигабайтом памяти она не умеет нормально пользоваться. Как только приложение сворачивают в систрей, она начинает сбрасывать его память в page-файл, даже если свободной памяти в системе — хоть задницей жуй. В результате — всё тот же могучий своп при свободной на 50%-60% памяти
Во всяком случае, таково поведение по умолчанию — с помощью твикеров ситуацию можно несколько выправить.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Sinclair, sorry, а не мог бы ты подсказать, как здесь эффективно сконкатенировать все же массив строк при том, что количество их определится в момент конкатенации?
С массивом все вообще просто. См. string.Join.
PD>Твой первый пример хорош, но там жестко 3 строки. На C++ конкатенацию массива строк в новую строку (я имею в виду не string из STL, а char*) я все же напишу однопроходным алгоритмом и при этом не будут использоваться никакие промежуточные буферы. Потому что задача по определению однопроходная.
Это как, интересно?
Не так ли:
public static string Join(IEnumerable<string> strings)
{
int len=0;
foreach(string s in strings)
len+=s.Length;
StringBuilder sb = new StringBuilder(len); // избегаем перевыделенийforeach(string s in strings)
sb.Append(s);
return sb.ToString();
}
? PD>Здесь это можно, используя только string, а не StringBuilder ?
Можно. Но уволят. PD>А если использовать StringBuilder, то ведь потом нужно копировать в string и в итоге 2 прохода все же ?
Нет. Там в большинстве случаев никакого копирования нету. UTSL, т.е. Reflector.
Код, который я привел, должен приводить к практически идеальному результату. Можно потестировать, что быстрее — подсчитывать суммарную длину или нет — в зависимости от количества строк в IEnumerable. Но это в любом случае эффекты второго порядка малости.
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Многие, например, неявно заинтересованы в том чтобы новая версия windows содержала больше ошибок... ПК>В отношении количества ошибок прогноз не вполне оправдывается: чем дальше после Windows 95, тем их меньше. В следующих версиях обещают еще лучше, т.к. вкладывают деньги в повышение качества разработки.
Вопрос спорный. Начиная от Windows 3.0 системы резко усложнялись (число даже строк кода росло в разы, где-то таблицу видел сравнительную, рост там нелинейный), а время разработок только сокращалось или оставалось прежним. Кроме того на все системы давит прессом обратная совместимость (со старыми ошибками и архитектурными промахами), но без этого нельзя, потому что несовместимая ни с кем ОС — никому не интересна. Ну и как в таких условиях обеспечить непрерывный рост надежности кода? Ведь чудес не бывает — пишешь быстро и много — получается хуже, как ни крутись... Вот например, Windows 2003 SP1 (исправление ошибок) занимает 270Mb в архиве (!), и содержит исправление практически к 95% всех компонент системы (Windows 2003 чистая занимает 350Mb в архиве). Ну и где тут рост качества кода? Бюллетени со знаком "критично" выходят почти каждый месяц — может это рост качества? Это рост популярности (ошибки стали искать и находить чаще, потому что это стало выгоднее), но не качества — число ошибок по-прежнему огромно! Да, та же Microsoft предпринимает шаги по улучшению качества и безопасности своих продуктов, но реальный конечный толк для пользователей (а не красивые слова от производителя) от этих шагов пока невелик. Наверное, из-за той же популярности продукции и сущестования целых линеек старых версий ОС...
Здравствуйте, pp2, Вы писали: pp2>В догонку — с mrozov я как раз не согласен. Я нигде не говорил что деньги определяют все. Я лишь посетовал, что увы все больше (в массовом коммерческом
pp2>Может Вы меня с кем-то путаете?
Помоему, это вы путаете с кем-то меня
Я как раз про деньги не сказал ни слова.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Это не совсем так. Например, те же функциональные языки часто "уделывают" ряд других, менее высокоуровневых "конкурентов". В общем, корреляция не вполне установлена.
Согласен. Но это специфичные решения.
>> А string вообще кошмар, но зато жутко удобный. ПК>Это к уровню языка отношения не имеет.
В честь чего. В С++ два основных типа строк.(пишу именно основных, чтоб не наезжали) Строка и нестрока, то есть string и char[]. string объект ООП — char[] наследие С. Кто из них высокоуровневая конструкция, а кто тормозная?
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Теперь осталось показать, что при разработке программ процесс происходит более-менее также...
Все к этому движется. Только все медленнее и медленнее.
Берем строку, делаем из нее массив строк и по запихиваем этот массив в Rows. А нельзя ли без того, чтобы массив создавать ? В C++ я бы просто прошел по этой строке strtok и добавил строки — без всяких дополнительных массивов.
На C++ конкатенацию массива строк в новую строку (я имею в виду не string из STL, а char*) я все же напишу однопроходным алгоритмом и при этом не будут использоваться никакие промежуточные буферы.
Здравствуйте, eao197, Вы писали:
E>Возьмем Janus. E> А уж поиск по базе сообщений по скорости с Opera вообще не сравнится.
насколько я понимаю им (поиском) никто не то что всерьез, а практически вообще не занимался — прикрутили и забыли, тут ни при чем ни .net ни что другое, просто не-за-ни-ма-лись
Здравствуйте, Odi$$ey, Вы писали:
E>>Возьмем Janus. E>> А уж поиск по базе сообщений по скорости с Opera вообще не сравнится.
OE>насколько я понимаю им (поиском) никто не то что всерьез, а практически вообще не занимался — прикрутили и забыли, тут ни при чем ни .net ни что другое, просто не-за-ни-ма-лись
Про .net я написал просто чтобы показать, что его объем нужно учитывать для определения объема инсталляции Janus. А совсем не к тому, что Janus тормозной из-за .net-а. Прошу не провоцировать
А поиск в Janus я привел как пример распространенного подхода: сделать работоспособный вариант без учета его эффективности. А потом, когда это станет проблемой, оптимизировать.
Тут уже кто-то сказал, что это "потом" никогда не наступает.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, gear nuke, Вы писали:
GN>ИМХО проблема не в языках. Многие алгоритмы имеют зависимости по данным (нельзя продолжать выполнение, пока не известен результат предыдущей операции). Да возьмём для примера любимый компилятор — даже если распараллелим компиляцию отдельных файлов, то как быть с линкером?
Оптимизировать последовательные операции. Пускай даже несколько эвристично. Это делает процессор, а почему бы и не компилятор?
GN>Можно вспомнить много таких "революционных" технологий даже на x86 — MMX, SSE, ... реальных выигрышей они не дают, если бы обычных регистров добавили, да нормальный (не стековый) FPU сделали — результат бы мог и лучше получиться. Но это бы была только *эволюция*.
Вот если бы сам x86 был стековый. Вот бы была крутизна.
GN>Ну это для тех, кто решает в какие акции деньги вкладывать . GN>Меня больше смущают медленные, загогулистые шины CPU <-> RAM. Перед тем, как ядро начнёт что-то там считать на своей мега-скорости, ему нужно что-то прочитать из медленной памяти. И если расширяя шину памяти можно немного поднять скорость, то от латентности никак не избавиться.
Я тебе и намекал, что средства для снятия нагрузки с общей памяти там есть. Это и локальные памяти, и те же шина между процами, с помощью которых можно пересылать результаты. С такой архитектурой можно спокойно делать и параллельные автоматы, и ступенчатый параллелизм.
Здравствуйте, GlebZ, Вы писали:
GN>>ИМХО проблема не в языках. Многие алгоритмы имеют зависимости по данным (нельзя продолжать выполнение, пока не известен результат предыдущей операции). Да возьмём для примера любимый компилятор — даже если распараллелим компиляцию отдельных файлов, то как быть с линкером? GZ>Оптимизировать последовательные операции. Пускай даже несколько эвристично. Это делает процессор
Процессор не делает этого. В общем случае невозможно в принципе выполнить следующую команду, когда результат её зависит от предыдущей.
GZ>а почему бы и не компилятор?
По причине выше.
GN>>Можно вспомнить много таких "революционных" технологий даже на x86 — MMX, SSE, ... реальных выигрышей они не дают, если бы обычных регистров добавили, да нормальный (не стековый) FPU сделали — результат бы мог и лучше получиться. Но это бы была только *эволюция*. GZ>Вот если бы сам x86 был стековый. Вот бы была крутизна.
Не уверен. Forth хороший язык, но что-то я видел мало людей, кто на нём пишет .
GZ>Я тебе и намекал, что средства для снятия нагрузки с общей памяти там есть. Это и локальные памяти, и те же шина между процами, с помощью которых можно пересылать результаты. С такой архитектурой можно спокойно делать и параллельные автоматы, и ступенчатый параллелизм.
Куда там в эту локальную память поместятся современные гигабайтные проги? .
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
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, GlebZ, Вы писали:
GZ>>{ GZ>> rows.Add(myString.Substring(i, l-i);
PD>А здесь не создается временная строка в результате работы Substring ? Если так написать
PD>string sTemp = myString.Substring(i, l-i); PD>rows(Add);
PD>то ясно, что создается. А это отличается только тем, что ссылка на эту строку записывается во временную переменную.
Именно, во временную переменную записывается ссылка на строку. Правда эта переменная будет оптимизирована и изъята JIT. Это с одной стороны, но с другой стороны в Net есть такое правило(которое подкрепляется языком), строку нельзя изменить. Можно создать только новую строку. Все методы изменяющие строки, не изменяют текущую строку, а создают новую. В результате — rows не будет делать копию строки. У него есть гарантия, то, что строка не будет никогда не изменена, которой он воспользуется. Поэтому процент случаев когда передается именно ссылка на строку, а не копируется строка на порядок выше чем в C++.
GZ>>Делает именно то, что заказывали. Без массива. PD>Зато с временными строками (== те же массивы)
Попрошу не путать временную строку и локальную ссылку на строку. В том что я описал выше, массивы != строка. И работа с ними существенно отличается.
Здравствуйте, GlebZ, Вы писали:
GZ>В честь чего. В С++ два основных типа строк.(пишу именно основных, чтоб не наезжали) Строка и нестрока, то есть string и char[]. string объект ООП — char[] наследие С. Кто из них высокоуровневая конструкция, а кто тормозная?
char[] не наследин С, а один из базовых типов. А string на его базе реализован.
PD>>А здесь не создается временная строка в результате работы Substring ? Если так написать
PD>>string sTemp = myString.Substring(i, l-i); PD>>rows(Add);
PD>>то ясно, что создается. А это отличается только тем, что ссылка на эту строку записывается во временную переменную. GZ>Именно, во временную переменную записывается ссылка на строку. Правда эта переменная будет оптимизирована и изъята JIT. Это с одной стороны, но с другой стороны в Net есть такое правило(которое подкрепляется языком), строку нельзя изменить. Можно создать только новую строку. Все методы изменяющие строки, не изменяют текущую строку, а создают новую. В результате — rows не будет делать копию строки.
Ты меня не понял. Я и не говорил, что rows будут. Я говорил, что Substring будет.
RB>М-м-м-м... Ну а если строк много, и их длина неизвестна?
Да хоть сотня, что от этого изменится ? И при чем здесь длина, где я ее использую ?
Ты идею прост не понял. sprintf возвращает длину выведенного куска символов (т.е очередной строки). Следующиий вывод идет с новой позиции, начиная за предыдущей строкой, после ее последнего символа. Ни один символ не просматривается и не копируется дважды. Строго однопроходной алгоритм.
>Вам RB>
RB>std::vector <std::string> >
RB>
RB> чем-то не нравится или я что-то пропустил?
При чем здесь вектор (массив) строк — не понимаю. Речь шла о конкатенации нескольких строк в одну.
GlebZ,
>>> А string вообще кошмар, но зато жутко удобный.
> ПК>Это к уровню языка отношения не имеет.
> В честь чего. В С++ два основных типа строк.(пишу именно основных, чтоб не наезжали) Строка и нестрока, то есть string и char[]. string объект ООП — char[] наследие С. Кто из них высокоуровневая конструкция, а кто тормозная?
Какое отношение к string имеет уровень языка, и string к уровню языка? В лучшем случае тут можно говорить об уровне абстракции. Но и в этом случае вряд ли можно говорить об универсальной зависимости производительности от уровня абстракции. Иными словами, в данном случае производится попытка сделать общий вывод (зависимость производительности от уровня языка) из частных моментов (производительность char[] vs. std::string), не вполне относящихся к ходу рассуждений (уровень языка здесь, имхо, ни при чем).
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
GlebZ,
> ПК>Теперь осталось показать, что при разработке программ процесс происходит более-менее также...
> Все к этому движется. Только все медленнее и медленнее.
Это только в фантазиях. На практике разработка программ как была, так и осталась штучным производством. О каком серийном производстве может идти речь, если одной из типичных активностей является рефакторинг? Это скорее проектирование и разработка экспериментальных образцов.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ты меня не понял. Я и не говорил, что rows будут. Я говорил, что Substring будет.
А я говорил, что никаких временных объектов при этом создаваться не будет.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Это только в фантазиях. На практике разработка программ как была, так и осталась штучным производством. О каком серийном производстве может идти речь, если одной из типичных активностей является рефакторинг? Это скорее проектирование и разработка экспериментальных образцов.
Имелась ввиду не тезис о серийности, а данная часть вашего постинга.
> Другой пример — корпусная мебель. Части одинаковые, а шкаф каждому свой нужен. Сборка — отверткой.
Теперь осталось показать, что при разработке программ процесс происходит более-менее также...
Другими словами, больше библиотек — меньше отсебятены. Надеюсь ты не будешь возражать что кол-во библиотек и их сложность значительно возрасли лет за 10. Или даже за пять?
S>Соответсвенно, взрослым, или как Вы изволили вырвзиться
S>
S>умелецы по части поедания фруктов не теряя достоинства
S>Имеют свои вилки, а дети свои.
S>Таким образом кесарю — кесарево...
S>ВЫВОД: S> Для S>
S> программиста проблемы с ДНК
S> нужны свои инструментальные средства
S>А для Взрослых — свои.
О! Именно об этом я и говорю. А так как "взрослых" программистов — ничтожное меньшинство, то мы и приходим к неутешительному выводу по поводу того, кому и что именно должны инструментальные средства.
S>ЗЫ ОЛЛ прошу извинить фривольный стиль, просто, я отчего-то веселый такой Сыну сегодня пол-года
Здравствуйте, gear nuke, Вы писали:
GN>Процессор не делает этого. В общем случае невозможно в принципе выполнить следующую команду, когда результат её зависит от предыдущей.
Почти да. Но он во первых, он может подготовиться к ней. Ну а в случае повышенной гранулярности, когда компилятор видит всю программу и гипотетический менеджер процессоров видит свободные мощности, то можно заняться и какой-то третьей задачей.
GN>>>Можно вспомнить много таких "революционных" технологий даже на x86 — MMX, SSE, ... реальных выигрышей они не дают, если бы обычных регистров добавили, да нормальный (не стековый) FPU сделали — результат бы мог и лучше получиться. Но это бы была только *эволюция*. GZ>>Вот если бы сам x86 был стековый. Вот бы была крутизна. GN>Не уверен. Forth хороший язык, но что-то я видел мало людей, кто на нём пишет .
Forth устарел. Но зато я видел много хороших людей которые знают о нем.
Я не имел язык как таковой. Я имел ввиду архитектуру вычислений. Она кстати была реализована в Эльбрусе.
GN>Куда там в эту локальную память поместятся современные гигабайтные проги? .
Где ты видел гигабайтные проги? Миф о гигабайтных массивах многим сносит голову. Структуры и данные больше не стали. Просто увеличилось их количество.
Ну а вопрос с оптимальностью заполнения локальных областей памяти конечно остается. Мое IMHO, что компилятор может их распределять более детерменированно и след., эффективно чем это делает кэш процессоров.
Здравствуйте, GlebZ, Вы писали:
GN>>Процессор не делает этого. В общем случае невозможно в принципе выполнить следующую команду, когда результат её зависит от предыдущей. GZ>Почти да. Но он во первых, он может подготовиться к ней. Ну а в случае повышенной гранулярности, когда компилятор видит всю программу и гипотетический менеджер процессоров видит свободные мощности, то можно заняться и какой-то третьей задачей.
С третьей задачей пролема такая: кеш сильно засоряется.
GN>>Куда там в эту локальную память поместятся современные гигабайтные проги? . GZ>Где ты видел гигабайтные проги? Миф о гигабайтных массивах многим сносит голову.
Ну я немного преувеличил .
GZ>Структуры и данные больше не стали. Просто увеличилось их количество.
Возьмём обычную программу в 5 мегабайт, даже без данных. А кеш всего-то 128Кб на Celeron (на все процессы!). Вот и получим в результате, постоянный "swap" из кеша в оперативку .
GZ>Ну а вопрос с оптимальностью заполнения локальных областей памяти конечно остается. GZ>Мое IMHO, что компилятор может их распределять более детерменированно и след., эффективно чем это делает кэш процессоров.
Как раз таки это близко к NP полной проблеме — кеш у каждого процессора по своему работает, да ещё и контроллер памяти вмешивается. Есть базовые правила, вроде выравнивания, но на современных процессорах это как раз не очень влияет. Говорить о хоть о какой-то автоматической оптимизации под кешь можно только относительно intel C++ compiler. здесь просто цыфры посмотрите, даже в код можно не вникать — "запросто" делается ускорение в 3 раза. Средний компилятор о таких трюках не знает совсем.
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
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Павел Кузнецов, Вы писали:
GZ>Не думал что подобная заметка из жизни вызывет флейм о вилках и детской посуде.
Дети, вилки — все это аналогии
GZ>Так что если говорить о промышленных языках, то я бы сказал что они есть компромисс — помочь первым, и не мешать вторым.
Именно к этому я и подвожу уважаемого коллегу mrozov, но только делаю это непринужденно и по аналогии
Позволю себе Вас перефразировать:
Т.е. ИНструментальные средства должны помочь первым и должны не мешать вторым ИМХО есстественно
Уважаемый коллега всего-навсего подверг резкой критике высказывание другого, не менее уважаемого коллеги:
"Если у программиста проблемы с ДНК, то лечится это не инструментальными средствами. Инструменты, напротив, должны давать возможности тем программистам, у которых с ДНК все в порядке."
Так как он (т.е. я) считает его слишком сильным и указывает на то, что считающие себя очень крутыми товарищи в этом бизнесе не одни.
Так что не думаю, что меня стоит "подводить" к этому тезису. Я вроде как именно на нем и стою. Обеими ногами.
Здравствуйте, Sinclair, Вы писали:
PD>>Твой первый пример хорош, но там жестко 3 строки. На C++ конкатенацию массива строк в новую строку (я имею в виду не string из STL, а char*) я все же напишу однопроходным алгоритмом и при этом не будут использоваться никакие промежуточные буферы. Потому что задача по определению однопроходная. S>Это как, интересно? S>Не так ли:
хъ
ИМХО лучше так
public static string Join(IEnumerable<string> strings)
{
ICollection<string> collection = strings as ICollection<string>;
if (collection != null)
return Join(collection);
int n = 0;
foreach(string s in strings)
++n;
string[] arr = new string[n];
n = 0;
foreach(string s in strings)
arr[n++] = s;
return Join(arr);
}
public static string Join(ICollection<string> strings)
{
ICollection<string> collection = strings as ICollection<string>;
string[] arr = new string[strings.Count];
strings.CopyTo(arr, 0);
return Join(arr);
}
public static string Join(string[] strings)
{
return string.Concat(strings);
}
Таким образом мы избегаем двойного копирования строк.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
А почему нет упоминания об 1С. Она очень эффективно для определенного круга задач.
И ее можно считать эффективной. Хотя перемножение матриц на ней ....
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, mrozov, Вы писали:
M>Уважаемый коллега всего-навсего подверг резкой критике высказывание другого, не менее уважаемого коллеги: M>"Если у программиста проблемы с ДНК, то лечится это не инструментальными средствами. Инструменты, напротив, должны давать возможности тем программистам, у которых с ДНК все в порядке." M>Так как он (т.е. я) считает его слишком сильным и указывает на то, что считающие себя очень крутыми товарищи в этом бизнесе не одни. M>Так что не думаю, что меня стоит "подводить" к этому тезису. Я вроде как именно на нем и стою. Обеими ногами.
Ок, Резюмируем окончательно:
Уважаемый коллега (Вы), не стойте 2мя ногами, сядьте:
всего-навсего подверг резкой критике высказывание другого, не менее уважаемого коллеги
при этом, уважаемый коллега ( опять Вы ), не разобрались, что формуолировка
у программиста проблемы с ДНК
Взята не менее уважаемым коллегой, не Вами (Павлом) здесь
Коллега, вы меня откровенно пугаете.
Я бы даже рискнул предположить, что один из нас явно сошел с ума.
Разговор, по моим представлениям, развивался так:
— С# позволяет комрадам с проблемами в ДНК жить на белом свете, а с++ — мешает
Павел на это:
— Задача инструментальных средств помогать не убогим, а нормальным.
Я на это:
— Задачи инструментальных средств каждый понимает по-своему.
Sinclair wrote:
> Гм. Мне не хотелось бы прослыть человеком, приносящим дурные вести, но > ты только что продемонстрировал способ внести в программу buffer > overrun vulnerability.
Здравствуйте, WolfHound, Вы писали: WH>ИМХО лучше так WH>
WH>public static string Join(IEnumerable<string> strings)
WH>{
WH> ICollection<string> collection = strings as ICollection<string>;
WH> if (collection != null)
WH> return Join(collection);
WH> int n = 0;
WH> foreach(string s in strings)
WH> ++n;
WH> string[] arr = new string[n];
WH> n = 0;
WH> foreach(string s in strings)
WH> arr[n++] = s;
WH> return Join(arr);
WH>}
Ну то есть ты пытаешься свести все к массиву, потому что для него есть встроенный метод string.Concat. На самом деле, ничего сверхестественного этот метод не делает. Он всего лишь заменяет null на string.Empty и подсчитывает длину, а затем вызывает
[c#]
private static string ConcatArray(string[] values, int totalLength)
{
string text1 = string.FastAllocateString(totalLength);
int num1 = 0;
for (int num2 = 0; num2 < values.Length; num2++)
{
string.FillStringChecked(text1, num1, values[num2]);
num1 += values[num2].Length;
}
return text1;
}
Если поковыряться в стрингбилдере, то он выдаст более-менее аналогичный код.
Ну то есть там на самом деле используется военная тайна string.AppendInPlace:
Основное отличие касается межпотоковой синхронизации.
В итоге, особой производительности ты тут не наиграешь. Зато налицо заметное усложнение кода, которое замазывает простую и стройную логику.
... << RSDN@Home 1.1.4 stable rev. 510>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
pp2,
> ПК> В отношении количества ошибок прогноз не вполне оправдывается: чем дальше после Windows 95, тем их меньше. В следующих версиях обещают еще лучше, т.к. вкладывают деньги в повышение качества разработки.
> Ну и где тут рост качества кода? Бюллетени со знаком "критично" выходят почти каждый месяц — может это рост качества?
Да. Весь следующий код будет содержать все эти исправления. Исправления по большей части касаются уже существовавшего кода, ошибки и уязвимости в котором существовали давно.
> Это рост популярности (ошибки стали искать и находить чаще, потому что это стало выгоднее), но не качества — число ошибок по-прежнему огромно! Да, та же Microsoft предпринимает шаги по улучшению качества и безопасности своих продуктов, но реальный конечный толк для пользователей (а не красивые слова от производителя) от этих шагов пока невелик.
Совершенно верно. Еще ни одного релиза не было с момента, когда Майкрософт начали, действительно, заботиться о качестве кода. Только сервис-паки (XP SP2 и 2003 SP). Обещают в висте значительно улучшенное качество кода и безопасность. Поживем-увидим.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, McSeem2, Вы писали:
ЗХ>>Мда. Энтузиасты и вольные художники формируют эту индустрию. ЗХ>>Ну да к вечеру вернется McSeem2, он тебе подробнее объяснит
ЗХ>>Конечно, а зачем?
MS>
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Собрался наконец написать. Минусов мне за эти тезисы поставят, это уж точно. Ну PD>что же — к счастью, я уже не в том возрасте, когда падение или рост рейтинга PD>могут серьезно повлиять на самочувствие.
PD>Итак...
<...> PD> Ну и к чему автор призывает, спросите Вы ? К поголовному возврату на PD>ассемблер PD>и к 64 Кбайтам ? К отказу от того пути, по которому сейчас пошло развитие ?
PD> Я не настолько наивен, чтобы к этому призывать. Просто одно скажу : PD>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>это возможно!
Есть такая парадигма: service-oriented architecture (SOA).
Она есть и успешно работает в MacOS X. Грубо — это когда пользователь вместо покупки программы за $400 с навороченным интерфейсом и ненужными (для него) фичами обходится мимтемным сервисом, но с нужной ему фичей за $25.
Сервис проверки орфографии ВО ВСЕХ текстовых полях, а не только в конкретном текстовом редакторе одной известной фирмы — вот одно из следствий такого подхода. Маленький и не тормозит.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>GlebZ,
>> ПК>Теперь осталось показать, что при разработке программ процесс происходит более-менее также...
>> Все к этому движется. Только все медленнее и медленнее.
ПК>Это только в фантазиях. На практике разработка программ как была, так и осталась штучным производством. О каком серийном производстве может идти речь, если одной из типичных активностей является рефакторинг? Это скорее проектирование и разработка экспериментальных образцов.
Программы не все разные. Примеры:
семейство текстовых редакторов,
интеренет магазины
системы управления складами
электронные библиотеки
управление документооборотом
Да, программыные продукты сильнее подверженны кастомизации так сказть, хотя и при сборке мебели кастомизация бывает
Хотелось бы, чтобы разработка шла по принципу сборки блоков, но действительно к этому не идем а еле ползем, чтож тут поделаешь, проблема индустрии, кстати очень интересная и заслуживающая отдельного обсуждения. Но, к примеру,
посмотрите на фреймворк 2.0 — сколько блоков там добавили И т.д.
Так что в идеале это производство, а то, что зачастую разработка вырождается в сборку штучных образцов — это не есть хорошо.
Безусловно, останутся области, где программы будут штучными(кстати и авто собирают иногда вручную на заказ), но это опять же не повод делать такие сильные обобщения, которые были в исходном посте.
Nickolay Ch,
> ПК> Это только в фантазиях. На практике разработка программ как была, так и осталась штучным производством. О каком серийном производстве может идти речь, если одной из типичных активностей является рефакторинг? Это скорее проектирование и разработка экспериментальных образцов.
> Программы не все разные. Примеры: > семейство текстовых редакторов, > интеренет магазины > системы управления складами > электронные библиотеки > управление документооборотом > > Да, программыные продукты сильнее подверженны кастомизации так сказть, хотя и при сборке мебели кастомизация бывает
Дело в наличии внутренних различий и в обусловленной этим разнице в процессе разработки. В отличие от серийного производства каждая новая программа, не разрабатываемая изменением уже существующей, проектируется заново (естественно, с учетом предыдущего опыта, но заново).
> Так что в идеале это производство, а то, что зачастую разработка вырождается в сборку штучных образцов — это не есть хорошо.
"В теории нет разницы между практикой и теорией. На практике она есть."
Так или иначе, похоже, ты согласен, что на данный момент разработка программ серийным производством не является. А что будет в будущем -- вопрос очень открытый.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
S>То что я написал — Вы не опровергли, а вместо этого согласились.
S>Соответсвенно вывод:
S> Разработчики инструментальных средств — считают так как Я и Павел Кузнецов ( Это ИМХО ), а не так как Вы .
Данный конкретный разработчик C# 3.0 считает, что его нововведения вполне безопасны и дружественны к новичкам.
... << RSDN@Home 1.2.0 alpha rev. 615 on Windows XP 5.1.2600.131072>>
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Теперь осталось определить, в какой степени мне важны интересы первых при выборе инструментальных средств, и на этом можно будет поставить точку в этой дискуссии. Пожалуй, с чем я легко могу согласиться, так это с тем, что в высказывании, процитированном выше, мне следовало подчеркнуть, что речь идет о тех инструментах, которые интересуют меня лично. Об остальных у меня мнения, кроме того, что они мне неинтересны, нет.
Ну, смотря кем работаешь. Если в большой команде, то твой выбор должен совпадать с выбором первых.
Ну а если твоя работа — что-то типа системного программиста, то уже не обязательно. Тут уже как выбор, типа все на С#, а наиболее изощренные(например системщики) на C++/CLI. И на unmanagement иногда. И чтоб с JavaScript + Html могли людям помочь. И чтобы к БД, интерфейсик приделать. И чтоб.... Для такого человека язык не главное. Главное — голова на плечах, и доступ к информации о том, о чем они слышат в первый раз.
Ну и третий случай, когда небольшая команда высокопрофессиональных программистов. Здесь уже ничего предположить нельзя. Если внешний заказ, то выбор по требованиям к продукту.
Стиль от переиспользования характеризуется тем, что при составлении программы стремятся максимально использовать то, что уже сделано — самим программистом, его коллегами или же вообще где-либо. Давно уже общепризнано, что в идеале на смену программированию как кодированию алгоритмов должно прийти программирование как сборка из заранее заготовленных блоков — сборочное программирование. Этот термин введен в 1978 г. Г. С. Цейтин позднее отделил это понятие от теоретических рассмотрений и представил его с программистской стороны. Заметим, что математики уже давно отказались от построения новых теорем (соответствующих в информатике программам) и новых понятий (соответствующих абстрактным типам данных) с пустого места. В математике весьма профессионально переиспользуются ранее полученные результаты. Здесь из-за концептуального единства системы понятий и строгих критериев обоснованности не возникает проблемы совместимости новых версий, которая зачастую губит попытки не только переиспользования, но и просто использования старых программ
Понятно, что при использовании готовых строительных блоков возможны потери. Тем не менее потенциальная выгода за счет переиспользования просто колоссальна. В математике, где имеются точные оценки, показано, что длину доказательства (читай — программы) можно сократить в БАШНЮ ЭКСПОНЕНТ РАЗ без существенной потери эффективности лишь за счет введения лемм (читай — использования уже построенных программ).
Рассмотрим две реальные ситуации, которые демонстрируют разработку, не ориентированную и ориентированную на переиспользование. В первой ситуации действует программист, работающий с очень развитой системой, в которой есть все. Тем не менее он пишет свою процедуру лексикографического упорядочивания строк, потому что «легче самому написать, чем найти, а потом ведь еще и подгонять придется». Вывод: во-первых, здесь начисто отсутствует стремление к переиспользованию, а во-вторых, переиспользованию могут препятствовать затруднения поиска того, что требуется включить в составляемую программу, а также проблемы совместимости версий.
Вторая ситуация — другая крайность. Программисту на Java потребовалось построить синтаксический анализ. На вопрос о том, как он это делает, получен ответ: «Зачем это знать? У меня есть пакет JavaCC, который все делает, как надо!» Вместе с тем, дальнейшие расспросы показали, что этот программист не представляет себе даже того, какого типа метод анализа поддерживает JavaCC, и, следовательно, ничего не может сказать о том, как задание грамматики для данного пакета связано с эффективностью анализа. Узнав возможные варианты, программист призадумался, но ничего менять не стал. Почему? Ответ простой: «Так ведь все уже работает!» Короче говоря, качество использования готовых компонентов системы зависит от знания о них.
Здравствуйте, gear nuke, Вы писали:
GN>С третьей задачей пролема такая: кеш сильно засоряется.
Опять кэш. Нету кэша. Есть область памяти которую загружает программа по полученным сведениям о своем выполнении во время компиляции и ресурсах компьютера в runtime.
GN>Возьмём обычную программу в 5 мегабайт, даже без данных. А кеш всего-то 128Кб на Celeron (на все процессы!). Вот и получим в результате, постоянный "swap" из кеша в оперативку .
Давай думать не про селерон, а про PIV с 2Mb. Или пересчитаем для Celeron. Если у нас 8 процов * 128 =1024Кб. Уже лучше.
GN>Как раз таки это близко к NP полной проблеме — кеш у каждого процессора по своему работает, да ещё и контроллер памяти вмешивается. Есть базовые правила, вроде выравнивания, но на современных процессорах это как раз не очень влияет. Говорить о хоть о какой-то автоматической оптимизации под кешь можно только относительно intel C++ compiler. здесь просто цыфры посмотрите, даже в код можно не вникать — "запросто" делается ускорение в 3 раза. Средний компилятор о таких трюках не знает совсем.
Мне не интересен сам вопрос про кэш. Кэш неуправляем и эвристичен. Я предполагаю более управляемую архитектуру.
Здравствуйте, eao197, Вы писали:
E>А поиск в Janus я привел как пример распространенного подхода: сделать работоспособный вариант без учета его эффективности. А потом, когда это станет проблемой, оптимизировать.
E>Тут уже кто-то сказал, что это "потом" никогда не наступает.
Это был я
Но зададим себе вопрос — "а оно надо"? Может быть и не нужен поиск в Janus? Или нужен?
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте, GlebZ, Вы писали:
GZ>Опять кэш. Нету кэша. Есть область памяти которую загружает программа по полученным сведениям о своем выполнении во время компиляции и ресурсах компьютера в runtime.
Можно называть это как угодно, но с технической точки зрения это всё равно будет кэш.
GN>>Возьмём обычную программу в 5 мегабайт, даже без данных. А кеш всего-то 128Кб на Celeron (на все процессы!). Вот и получим в результате, постоянный "swap" из кеша в оперативку . GZ>Давай думать не про селерон, а про PIV с 2Mb.
Это не сильно меняет ситуацию. Разница в размерах програм и размером кэша — порядок.
GZ>Или пересчитаем для Celeron. Если у нас 8 процов * 128 =1024Кб. Уже лучше.
Для каждого-то CPU всё равно останется 128.
GZ>Мне не интересен сам вопрос про кэш. Кэш неуправляем и эвристичен. Я предполагаю более управляемую архитектуру.
По сути, Вы предлагаете управляемый кэш. Это способно дать выигрыш. И сущесвующие методики работы с кэшем тоже дают выигрыш. Вопрос в том, почему до сих пор нет ни одного компилятора использующего это эффективно?
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
GlebZ,
> Стиль от переиспользования характеризуется тем, что при составлении программы стремятся максимально использовать то, что уже сделано — самим программистом, его коллегами или же вообще где-либо. <...>
Не важно это: все равно проектировать заново придется, даже при использовании готовых "блоков" (модулей, компонент и т.п.).
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Ты меня не понял. Я и не говорил, что rows будут. Я говорил, что Substring будет. GZ>А я говорил, что никаких временных объектов при этом создаваться не будет.
Объясни, пожалуйста , тогда еще раз. Вот твой код
int i, l=0;
while ((i=myString.IndexOf(",", l))!=-1)
{
rows.Add(myString.Substring(i, l-i);
l=i;
}
Здесь при вызове rows.Add ей передается строка, так ? Эта строка должна быть создана , так ? Путем вызова Substring. И все это делается в цикле. Я согласен с тем, что ссылка на эту строку не хранится у тебя, и сразу после Add на эту временную строку ссылок больше нет и она есть мусор для GC, но ведь она все же создается ? Или нет ?
Здравствуйте, Павел Кузнецов, Вы писали:
>> Стиль от переиспользования характеризуется тем, что при составлении программы стремятся максимально использовать то, что уже сделано — самим программистом, его коллегами или же вообще где-либо. <...>
ПК>Не важно это: все равно проектировать заново придется, даже при использовании готовых "блоков" (модулей, компонент и т.п.).
Естественно . Каждый шкаф тоже заново рисуют по пожеланиям клиента.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Это уже совсем несерьезно. Человек спрашивал, как технически, т.е. с помощью каких средств языка С++ можно такое сделать. Я ему и показал. Неужели я не понимаю, что 1000 может не хватить ???? S>Я не знаю чего ты понимаешь, я не телепат. Но я вижу, что ты привел код, который запрещено применять в коммерческом программировании под страхом смертной казни. Мы приводим такой код только в курсе сетевых технологий, как пример заведомо небезопасного подхода.
Истина всегда конкретна. Если речь идет о неопределенном количестве неизвестной заранее длины строк — согласен. Если же необходимо сконкатенировать вполне предполагаемый набор строк с суммарной длиной, которую можно заранее оценить — ничего криминального не вижу. А оценить ее бывает вполне возможно. И не надо пугать меня смертной казнью — я такое не раз делал в коммерческих приложениях, и они, слава богу, вполне работают. Потому что я прекрасно знал, какой максимальный объем здесь может получиться. Просто потому что больше получится не может — нет такого в той стране, для которой я это делал. Нет, и все. Не бывает и никогда не будет.
PD>>А, прошу прощения, если не знать или хотя бы предполагать общий размер, то задача вообще не разрешима в однопроходном варианте. Потому как нельзя копировать в буфер, не выделив его предварительно. А длины в С++ не хранятся, в отличие от С#. На Паскале можно, там они хранятся. S>И после этого кто-то будет обвинять C# в неэффективности???
Естественно. Оверхед на хранение длины строки, которая чаще всего и не нужга. .
S>Я приводил пример пессимального кода, который на шарпе приводит к квадратичной зависимости от полной длины строки. С точки зрения того алгоритма, два прохода или один — не так важно. Все равно мы имеем O(N).
Я все же полагаю, что AN < 2AN при любом положительном A .
Даже наличие хранимой длины не слишком изменяет ситуацию — если длины фрагментов примерно одинаковы, то их количество тоже пропорционально суммарной длине строки, и мы опять имеем O(N). Меняется только константа перед ней.
Вот именно. Кстати, ты на 100% уверен, к примеру, что AN всегда лучше, чем BNlogN ?
S>Видел своими глазами пример. Как знаток x86 — ассемблера страшно раскритиковал код, сгенерированный VC 7.1 в релизе для приведенного мной фрагмента. Действительно, его код был красивше. А студийный — тихий ужос. Какие-то лишние джампы, как-то там регистры странно использовались... Увы, когда мы сравнили время — студия победила.
Ну и что ?
>Видать, ее оптимизатор лучше знает особенности спаривания команд и устройство конвеера
чем "знаток x86", только и всего.
>После этого я еще немножко верю в то, что суперкрутой спец сможет написать более эффективный код вручную.
Ну если он "лучше знает особенности спаривания команд и устройство конвеера", чем VC, то и сможет, я полагаю.
>Но, во-первых, для этого ему потребуется что-то типа Intel VTune
Вполне возможно, а может, и нет, если он сам "лучше знает особенности спаривания команд и устройство конвеера"
>, а во-вторых, чем эффективнее будет этот код, тем больше риска, что на другой модели процессора он окажется в дупе. А в компиляторе я просто переброшу ключик "Target Processor" и усё.
Вот это единственное серьезное возражение. Но процессоры ежедневно не появляются, а на асме оптимизируют под некий процессор, естественно. Если нужна максимальная призводительность, то при появлении нового процессора, естественно, придется ему пересмотреть код. Кстати, авторам VC — пересмотреть генератор кода. С помощью VTune или своей головы только
>Кстати, джиту еще лучше — ему не надо оптимизировать под "blend".
Ему не надо. Авторам JIT надо
S>А наивные попытки улучшить код, основанные на прочитанной 10 лет назад книжке "Справочное руководство по Intel 80386" способны только просадить эффективность.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, GlebZ, Вы писали:
GZ>>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>Ты меня не понял. Я и не говорил, что rows будут. Я говорил, что Substring будет. GZ>>А я говорил, что никаких временных объектов при этом создаваться не будет.
PD>Объясни, пожалуйста , тогда еще раз. Вот твой код
PD>int i, l=0; PD>while ((i=myString.IndexOf(",", l))!=-1) PD>{ PD> rows.Add(myString.Substring(i, l-i); PD> l=i; PD>}
PD>Здесь при вызове rows.Add ей передается строка, так ? Эта строка должна быть создана , так ? Путем вызова Substring. И все это делается в цикле. PD>Я согласен с тем, что ссылка на эту строку не хранится у тебя, и сразу после Add на эту временную строку ссылок больше нет и она есть мусор для GC, но ведь она все же создается ? Или нет ?
Создается, но она не мусор. Строка в Net — immutable. Строка не может быть изменена, можно создавать только новые. Row возьмет ссылку на строку и будет оперировать именно им. Он спокойно может сохранять у себя ссылку на строку, передавать ее другим, не боясь что кто-то изменит ее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Не важно это: все равно проектировать заново придется, даже при использовании готовых "блоков" (модулей, компонент и т.п.).
Только придется проектировать исходя из возможностей компонент, и знания о нем как о черном ящике.
Здравствуйте, Sinclair, Вы писали:
S>Видел своими глазами пример. Как знаток x86 — ассемблера страшно раскритиковал код, сгенерированный VC 7.1 в релизе для приведенного мной фрагмента. Действительно, его код был красивше. А студийный — тихий ужос. Какие-то лишние джампы, как-то там регистры странно использовались...
Из интереса решил посмотреть на этот тихий ужас. VC 7.1 , Release
; 9 : int a[100000];
; 10 : for(int i = 0; i < 100000; i++)
Что-то я никакого тихого ужаса не вижу. Код, понятный даже тем, кто "прочитал 10 лет назад книжке "Справочное руководство по Intel 80386" и ничего сверх этого руководства для его понимания не требуется.
Хотя и не scasd. Надо будет написать со scasd и сравнить. Увы, через полчаса лекция.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Sinclair, Вы писали:
S>>Видел своими глазами пример. Как знаток x86 — ассемблера страшно раскритиковал код, сгенерированный VC 7.1 в релизе для приведенного мной фрагмента. Действительно, его код был красивше. А студийный — тихий ужос. Какие-то лишние джампы, как-то там регистры странно использовались...
PD>Из интереса решил посмотреть на этот тихий ужас. VC 7.1 , Release
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Это все верно, но тут ты играешь на том, что эти подстроки нужны и дальше (в данном случае будут использованы в rows).
Ага. Но это очень частый случай.
PD>А вот когда они дальше как таковые не нужны (т.е нигде храниться не будут) — тут-то ты и проиграешь.
В большинстве случаев нужны. Иначе никак кроме подпоркой такую строку не назвать. Но безусловно есть и описанный случай.
string str=str.Substring(1,10).ToUpper(); //здесь действительно есть промежуточная строка.
В случае C++ можно построить без промежуточной строки. Тут можно только упомянуть, что GC с такими промежуточными строками на ура.
PD>p=strtok(myString,","); PD>while(p) PD>{ PD> printf("%d\n",p); PD> p = strtok(NULL,",") PD>}
Да уж. Действительно сильно искуственный пример.
strok — злобная функция, так как она использует static данные на уровне CRT. И соответсвенно, два выполнения strtok — прямой путь к нетрадиционному сексу. Лучше всего вообще забыть о ее существовании.
В большинстве случаев, если обработки строки распределена. и обработка меняет состояние строки, придется делать промежуточные строки. В случае Net — это придется делать и при локальной обработке.
PD>В итоге для того, чтобы распечатать подстроки, ты создал их, напечатал, и, конечно, они стали добычей GC. А я их не создавал. Правда, строку испортил, но это уж так strtok сделана. Могу свою функцию написать, которая то же сделает, но строку портить не будет.
Именно. А если у кого-то была ссылка на строку, то тебе надо делать копии. Но чаще придется делать копии, из-за того что ты не можешь предположить, будет строка изменяться, или нет. Тут эта проблема решена.
PD>Если считешь мой пример искусственным — хорошо, пусть в задаче требуется разбить на слова, а потом каждое слово проверить каким-то образом. Я опять-таки подстроки делать не буду, а ты будешь.
По крайней мере одну придется делать(и не дай бог что TestWord тоже использует strtok):
gear nuke wrote: >> > *почему* до сих пор нет ни одного компилятора использующего это > эффективно? > > R>Современное управление кешем неполно (у кеша всегда есть и своё мнение > R>кроме prefetchnta) и непереносимо, поэтому никто не заморачивается? > > Вот именно. ИМХО для этого по-хорошему нужен JIT компилятор, а такое > есть пока только под .NET, можно сказать. В зачаточном состоянии, скорее > всего. Обычные компиляторы сколько лет до ума доводили.
Зачем JIT? Хотя бы нормальная система команд. Тогда они её друг у друга
лицензируют. Но это должна быть система, позволяющая объяснить
процессору, что эти данные дороже, чем более новые.
Чтобы определить в 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
gear nuke wrote: > R>Зачем JIT? > > Чтобы определить в runtime характеристики кэша и прочего и сгенерировать > оптимальный код на лету.
Тогда лучше сразу не мелочиться и не суетиться при оптимизации. Ну Вы
поняли, о чём я. Впрочем, если система команд разумна, то управление
кеш-памятью может идти хоть в ран-тайме — всё равно ускорение доступа к
главным данным окупит всё. Главное, чтобы она была.
ПК>Дело в наличии внутренних различий и в обусловленной этим разнице в процессе разработки. В отличие от серийного производства каждая новая программа, не разрабатываемая изменением уже существующей, проектируется заново (естественно, с учетом предыдущего опыта, но заново).
Если позволите, то я слегка в этот разговор вмешаюсь, несколько в иной плоскости.
Много сейчас говорится о повторном использовании кода. Это рассматривают как один из важных критериев его качества. Но вот такая (может быть, теоретическая) проблема возникает.
Если речь идет о библиотеках типа STL, MFC etc. или компонентах для рынка — все ясно. В общем, они и рассчитаны на то, что их именно повторно будут использовать.
А вот когда речь идет о коде, разработанном для данного проекта, то во многих случаях Copyright на этот код получит заказчик. Так что повторно его использовать законным путем можно только в том случае, когда новый проект будет для того же заказчика (или когда заказчик прежний разрешит). В противном случае повторное использование есть нарушение Copyright.
Интересно было бы узнать — насколько часто программисты действительно повторно используют свой код ? Т.е не идеи из него используют для нового кода, а прямо-таки класс/функцию/компонент свой берут и в новый проект втыкают. Естественно, речь не идет о библиотеках.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Есть такой класс программистов — программисты на Visual Basic. VB как-то в России не слишком популярен ИМХО и признаваться, что на нем пишешь, даже как-то стыдно считалось . А вот в мире он весьма популярен, где-то мне встретилось утверждение, что в мире около 1 млн. программистов на VB. За то. что мне память здесь не изменяет — не поручусь, так что критиковать это утверждение не надо. И потом, неизвестно кого они туда включили — может, школьников средних школ тоже
PD>Так вот, эти самые программисты на VB свою работу делали, а вот эффективности от них никто и не ждал. Потому что программы для массового использования они не делали, а делали для данного конкретного случая, порой для себя, или для заказчика, которому она нужна, а торговать он ей вовсе не собирается. Кстати, если во времена своих химических расчетов имел бы PC с VB — вполне возможно, на нем бы и начал свою карьеру. Просто, удобно, легко...
думаю ты сильно ошибаешся, утверждая что Visual Basic есть средство для
наколенного написания программ. Это полноценный mainstream продукт для разработки
софта. Как раз для приложений массового использования. А то что он использовался в основном для in house софта (которым не надо торговать) — так только потому, что это основной это именно in house приложения.
Здравствуйте, Pavel Dvorkin, Вы писали:
GZ>>strok — злобная функция, так как она использует static данные на уровне CRT.
PD>Хуже. Она использует __declspec(thread). Иначе, сам подумай, что будет, если ее начнут из разных потоков вызывать
Для этого достаточно одного потока.
PD>Во многих и даже очень многих могу PD>const char* p — и я имею право предположить, что не будет.
+1. К сожалению const многие не ставят. Поэтому приходится лазить по коду и узнавать, можно или нельзя. Ну а в Net const в параметрах нет.
GZ>>По крайней мере одну придется делать(и не дай бог что TestWord тоже использует strtok): GZ>>
PD>Да зачем же ? Пусть TestWord себе благополучно эту строку исследует (например, является ли слово палиндромом). Начало — p, конец — '\0', зачем мне тут подстроки в отдельный буфер копировать, когда и на месте все ясно ?
Честно говоря, аналогом можно считать больше wstring чем char*. Char* — это область памяти с которой можно сильно сглюкавить, что для Net противозаконно. Я когда код пишу, подразумеваю что им будут пользоваться и другие. А другие обычно в код функции не смотрят, а ориентируются по названию и параметрам. Поэтому всегда пытаюсь показать, что строка может быть изменена или нет, тем же const. Но бывает и такое:
if (bla-bla)
strupr(lpStr);
То есть, не обязательно строка будет изменена. А защищать ее как-то уже надо. В Net над таким задумываться не надо. Поскольку это не value объект, он всегда передается по ссылке. А возвращаться может только в виде другой строки(или другой ссылки, если строка не изменилась). Именно в том, что это именно неvalue объект, и не хранится в стеке, скорее и стало определяющим фактом для выбора такого "функционального" пути.
Но особым плюсом такого подхода можно указать следующее:
string str1="this is the string";
.......
string str2="this is the string";
Строка str1 и str2 — несмотря на то, что являются разными ссылками, в действительности ссылаются на одну и ту же строку. Строка лежит в метаданных. Достаточно частый случай что константно описывают одну и ту же строку в разных частях программы. Компилятор сохраняет строку в одном и том-же месте.
Здравствуйте, GlebZ, Вы писали:
PD>>Хуже. Она использует __declspec(thread). Иначе, сам подумай, что будет, если ее начнут из разных потоков вызывать GZ>Для этого достаточно одного потока.
Только при некорректном использовании.
GZ>Честно говоря, аналогом можно считать больше wstring чем char*. Char* — это область памяти с которой можно сильно сглюкавить
или сделать что-то очень эффективно. Вообще возможность сделать что-то эффективно всегда связана с большей возможностью сглюкавить. Крайний пример такого утверждения — ассемблер.
GZ>
GZ>if (bla-bla)
GZ> strupr(lpStr);
GZ>
Да. Классический вариант inplace обработки.
GZ>То есть, не обязательно строка будет изменена. А защищать ее как-то уже надо. В Net над таким задумываться не надо. Поскольку это не value объект, он всегда передается по ссылке. А возвращаться может только в виде другой строки(или другой ссылки, если строка не изменилась).
Вообще-то идея string как неизменяемого объекта в NET мне нп\равится (правда, идея не Net, а Java принадлежит, а может, и кому-то до нее — не знаю). Разумеется, при наличии еще и StringBuilder.
GZ>Но особым плюсом такого подхода можно указать следующее: GZ>
GZ>string str1="this is the string";
GZ>.......
GZ>string str2="this is the string";
GZ>
GZ>Строка str1 и str2 — несмотря на то, что являются разными ссылками, в действительности ссылаются на одну и ту же строку.
Такое поведение и в С++. Еще в Borland C++ 3.1 было(merge duplicate strings). Только там оно управляемо через опции компилятора. Можно и отказаться
>Строка лежит в метаданных.
В С++ — в readonly данных (т.е. страница readonly). Изменить строку не удастся без шаманства.
Здравствуйте, Igor Sukhov, Вы писали:
IS>думаю ты сильно ошибаешся, утверждая что Visual Basic есть средство для IS>наколенного написания программ. Это полноценный mainstream продукт для разработки IS>софта. Как раз для приложений массового использования. А то что он использовался в основном для in house софта (которым не надо торговать) — так только потому, что это основной это именно in house приложения.
Игорь, я вовсе не утверждаю этого И более того, если есть 1 млн. программистов на нем, то они за что-то деньги свои получают. Я о другом говорю. До сих пор была определенная разница между тем, что можно было хотя бы в принцие писать на VB и тем, для чего VB не может рассматриваться как среда разработки вообще.
Например, я сильно сомневаюсь, что Adobe могла бы рассматривать VB как среду для разработкт своих продуктов. И даже на порядок более простой какой-нибудь file downloader тоже на VB никто писать не стал бы. Не то средство.
А вот будет ли Adobe переписывать PhotoShop на .net — не знаю. Надеюсь, что нет
Здравствуйте, McSeem2, Вы писали:
MS>Но зададим себе вопрос — "а оно надо"? Может быть и не нужен поиск в Janus? Или нужен?
Янус не стоит приводит в качестве примера. Облик януса определяется не столько потребностями пользователей в целом, сколько потребностями его разработчиков.
Это вобще очень забавный проект — с одной стороны open source, с другой цели его сугубо утилитарные (очень мало влияют соображения престижа или самореализации).
PD>Так вот, у меня впечатление такое, что этот стиль VB попросту начинает проникать в те области, куда программистов VB раньше и на пушечный выстрел не подпускали, да они и сами не стремились, так как знали, что им там делать нечего — не влезут они с VB в имеющиеся ресурсы, не добьются нужной производительности. А ресурсы увеличились — и они пошли!
На самом деле большинство требуемых программ бухгалтерские, складские, зарплата. Там много писанины, но нет задач оптимизации по скорости ,вернее есть но их не так много и решаются интеграцией через различные Dll где они решаются более эффективно на типизированных компилированных языках. Посмотри на 1С зарплаты 1С программистов, итд.
В свое время Delphi был изгоем для большинства сишников, сейчас Net. Каждый инструмент для решения своей задачи, но в большинстве случаев нужна скорость разработки, библиотеки классов итд. Железо совершенствуется и там,где в свое время было лимитирующим процессом, сейчас нет проблем так как скорости возросли в 10 раз за период в 5 лет.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Хотел я в исходном постинге напомнить про один принцип. Потом решил, что введет ненужную игривость
PD>KISS — Keep It Simple, Stupid!
а ты уверен, что знаешь, что именно это утверждение значит?
Что соображения удобства чтения и модификации кода стоят выше соображений эффективности
почитай Реймонда, например.
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Хотел я в исходном постинге напомнить про один принцип. Потом решил, что введет ненужную игривость
PD>>KISS — Keep It Simple, Stupid!
Д>а ты уверен, что знаешь, что именно это утверждение значит?
Уверен
Д>Что соображения удобства чтения и модификации кода стоят выше соображений эффективности
А это вопрос спорный. Смогтря для чего, по крайней мере.
Д>почитай Реймонда, например.
Здравствуйте, Pavel Dvorkin, Вы писали:
Д>>Что соображения удобства чтения и модификации кода стоят выше соображений эффективности
PD>А это вопрос спорный. Смогтря для чего, по крайней мере.
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
Д>>>Что соображения удобства чтения и модификации кода стоят выше соображений эффективности
PD>>А это вопрос спорный. Смогтря для чего, по крайней мере.
Д>Спорить тут абсолютно не о чем. Почитай книгу.
Почему, если в некоторой книге что-то написано,, то спорить уже абсолютно не о чем ? Там что — евангелие или тезисы ЦК КПСС к NNN съезду?
Из протокола заседания комиссии по разработке нового автомобиля.
Директор фирмы :
Уважаемые господа!
Мы приступаем к разработке автомобиля нового поколения с использованием новейших технологий. Вот какими принципами вы должны руководствоваться :
Если автомобиль будет сжигать 100 литров бензина на 100 км пути — это не страшно. Нефти еще много, это не ресурс.
Если габариты автомобиля таковы, что, будучи на самой правой полосе шестрирядной дороги, он выходит частично на полосу встречного транспорта — это тоже не страшно. Кто захочет — объедет, а до остальных нам дела нет.
Но вот если вы не сможете с закрытыми глазами развинтить его и заменить мотор — всех уволим!
Если хоть один механик на станции ТО не сможет это сделать — всех уволим!
А если это не сможет кто-то сделать через 10 лет, когда вас уже в фирме не будет — на том свете найдем и угольков подкинем.
Вопросы есть ? Приступайте!
P.S. А вообще-то я не против автомобиля новейших технологий. Лишь бы он не отнимал ресурсов больше, чем существующие.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Почему, если в некоторой книге что-то написано,, то спорить уже абсолютно не о чем ? Там что — евангелие или тезисы ЦК КПСС к NNN съезду?
евангелие — это близко к истине
PD>Из протокола заседания комиссии по разработке нового автомобиля.
PD>Директор фирмы :
PD>Уважаемые господа!
PD>Мы приступаем к разработке автомобиля нового поколения с использованием новейших технологий. Вот какими принципами вы должны руководствоваться :
PD>Если автомобиль будет сжигать 100 литров бензина на 100 км пути — это не страшно. Нефти еще много, это не ресурс. PD>Если габариты автомобиля таковы, что, будучи на самой правой полосе шестрирядной дороги, он выходит частично на полосу встречного транспорта — это тоже не страшно. Кто захочет — объедет, а до остальных нам дела нет. PD>Но вот если вы не сможете с закрытыми глазами развинтить его и заменить мотор — всех уволим! PD>Если хоть один механик на станции ТО не сможет это сделать — всех уволим! PD>А если это не сможет кто-то сделать через 10 лет, когда вас уже в фирме не будет — на том свете найдем и угольков подкинем.
пусть лучше жрет топливо, но зато не глохнет при повороте руля на угол чуть больше обычного
и не взрывается после замены зеркала заднего обзора на другую модель
про пример с sprintf еще не забыл?
Здравствуйте, Дарней, Вы писали:
Д>евангелие — это близко к истине
1.Не сотвори себе кумира!
2. Не относись ко всему чересчур серьезно. Имей чувство юмора.
Д>пусть лучше жрет топливо, но зато не глохнет при повороте руля на угол чуть больше обычного Д>и не взрывается после замены зеркала заднего обзора на другую модель
А почему он глохнуть-то должен ? Можно ить обычных размеров сделать, и с обычным расходом горючего. Тойота вроде не глохнет, и Мерседес тоже. И размерами они не с ТУ-154.
А вот если у вас только Запорожец получается, то научитесь делать хотя бы Тойоту. Но обычных размеров.
Д>про пример с sprintf еще не забыл?
Нет. Зачем мне про него забыть — он примерно на 1000 компьютеров работает в моем коде, и пока никто не жаловался и не будет — потому как не может быть там никакой проблемы.
А кстати, о sprintf. Меня, как я помню, обвиняли в том. что возможно переполнение буфера. Не спорю, теоретически возможно. Но ведь и в этом операторе переполнение возможно
int nScreenArea = nScreenWidth * nScreenHeight;
А вдруг у нас будет экран 80000*60000. Сразу все перестанет работать.
Так вот, мой sprintf вызовет переполнение буфера. Обязательно вызовет. Но не раньше, чем этот пример сгенерирует integer overflow
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>1.Не сотвори себе кумира!
мы ведь говорили про принцип KISS? вот у меня есть предположение, что люди, которые стояли у истоков Юникс, знают намного больше нас с тобой о его точном значении
PD>2. Не относись ко всему чересчур серьезно. Имей чувство юмора.
имею. каждый день
PD>А почему он глохнуть-то должен ? Можно ить обычных размеров сделать, и с обычным расходом горючего. Тойота вроде не глохнет, и Мерседес тоже. И размерами они не с ТУ-154. PD>А вот если у вас только Запорожец получается, то научитесь делать хотя бы Тойоту. Но обычных размеров.
мы ведь говорим о программах, а не о машинах?
а вот как раз они глохнут. и "взрываются". причем регулярно
поэтому давайте сделаем сначала то, что будет нормально ездить и возить грузы. Пусть и не очень быстро, зато с гарантированной доставкой из точки А в точку Б. Причем в целом и непритронутом виде.
PD>Нет. Зачем мне про него забыть — он примерно на 1000 компьютеров работает в моем коде, и пока никто не жаловался и не будет — потому как не может быть там никакой проблемы.
многие так думали. пока жареный петух в одно место не клюнул
PD>А кстати, о sprintf. Меня, как я помню, обвиняли в том. что возможно переполнение буфера. Не спорю, теоретически возможно. Но ведь и в этом операторе переполнение возможно
PD>int nScreenArea = nScreenWidth * nScreenHeight;
PD>А вдруг у нас будет экран 80000*60000. Сразу все перестанет работать.
PD>Так вот, мой sprintf вызовет переполнение буфера. Обязательно вызовет. Но не раньше, чем этот пример сгенерирует integer overflow
разница в том, что этот код не вызовет порчу стека. а sprintf — вызовет
улавливаешь разницу?
кстати говоря, во многих серьезных конторах за использование любой функции из семейства printf нещадно бьют по рукам. И даже более серьезно — по кошельку.
Здравствуйте, Pavel Dvorkin, Вы писали:
Д>>мы ведь говорили про принцип KISS? вот у меня есть предположение, что люди, которые стояли у истоков Юникс, знают намного больше нас с тобой о его точном значении
PD>Не понял. Или ты имеешь в виду, что я неправильно расшифровал аббревиатуру ?
расшфировал аббревиатуру — правильно. Понял смысл — неправильно.
Не вижу вообще смысла спорить на эту тему. Есть общепринятое значение, которое вкладывается в это выражение. А если ты решил для себя, что будешь называть стол стулом — то это исключительно твои частные проблемы.
PD>Не без этого, не спорю. Но бороться за то, чтобы этого не было, надо с соразмерными затратами. Если, конечно, речь не идет о программе управления ядерным реактором. Если ICQ раз в месяц падает, то еще вопрос — нужна ли мне ICQ, которая падает раз в 3 месяца и жрет памяти в 3 раза больше.
раз в месяц? да вы, батенька, оптимист
PD>Нет, не пойдет. Потому что если с меня за эту поездку на самоновейшем самолете возьмут из Омска в Москву $1000, я предпочту обычный российский поезд, который довезет меня за $100, хотя, возможно, слегка опоздает. Кстати, и риск аварии там не больше, чем у самоновейшего самолета.
вооот! о чем я собственно и говорил
"самоновейший самолет" — это как раз твое гипотетическое быстрое и надежное ПО
медленный поезд — это то тормозное, но работающее ПО, которое есть сейчас
PD>Ну несерьезно это. Есть страна, для которой я это делал. Есть у них в стране некая информация (извини, но деталей рассказывать не буду). Эта информация там появилпась, когда еще никаких компьютеров на свете не было, а может, и автомобилей не было. И вот я эту информацию в некий буфер заношу. И то, что она никак не может быть больше, чем 500 символов — гарантия в 101%. Никогда не может, ну так же, как имя русское не может быть длиной в 500 символов. А времени считать эту длину абсолютно нет, потому как на все про все мне дано 100 мсек. И в этих условиях ты все же будешь утверждать, что buffer overrun возможен ?
сразу вспоминается случай, когда разработчики решили, что длина серии паспорта не может быть больше 10 символов (может быть и не десять, не помню точно)
А потом приехал парень из страны, где серия паспорта имела больше символов. И бедолага несколько месяцев ходил по инстанциям.
еще могу напомнить про случай, когда разработчики решили "ну не может эта переменная переполниться! ни никак! потому что этого не может быть никогда!"
а потом в траекторию полета внесли изменения, и аппарат с треском рухнул.
PD>Нет, не улавливаю. все равно это кончится неверным поведением программы и в конце концов крахом. Причем скорее всего не здесь, а где-то еще. Так что разницы я не улавливаю. Или ты хочешь сказать, что buffer overrun — это намного хуже, чем integer overflow ? По мне, один черт — все равно дальше ничего хорошего не будет.
намного, намного хуже. А ты не догадываешься, почему?
в той ветке вроде бы вполне доходчиво объяснили
PD>А это от ситуации зависит. В том проекте, в котором я участвовал, мне все было разрешено, кроме одного — низкой скорости работы. Занял бы на диске лишний Гбайт — простили бы. ОП использовал бы в 2 раза больше, чем надо — тоже простили бы. А вот уложиться я должен был в 100 мсек. Кровь из носу. Потому что если 200 мсек займет — это кончится просто тем, что данный образец будет снят с обработки по нехватке времени, а тем самым число необработанных образцов увеличится. А обрабатывается таких образцов в день примерно 30,000 только на одной машине, и на каждый образец дается не более 3 сек. И за это время к моему ПО делается 10-15 запросов плюс, естественно, то время, которое нужно на оставшуюся часть, а оно есть примерно 60% общего времени. А машин примерно 1000. Борьба шла за каждый процент. И мне все прощалось, только бы быстрее. И сделал я им вместо 100 мсек 20-30 мсек, и были они в полном восторге
PD>А лишних Гбайтов я , кстати, не использовал. И лишней ОП — тоже. Ну разве что самую малость — буфер там был один с запасом в 64 Кбайта
и зря. Вполне возможно, что это позволило бы поднять скорость без ущерба для надежности.
Здравствуйте, eao197, Вы писали:
E>Зато как же обломно после таких проектов формочки на JSP рисовать и SQL запросы сочинять! E>Блин, словами не передать. E>Зато антураж какой! Рефакторинг, юниттестинг, код ревью, баг трекинг, UML, XML, SQL,... память нынче не ресурс... давай, давай, сроки горят... память нынче не ресурс... давай, давай, все должно было работать еще вчера... память нынче не ресурс... Об эффективности программ
Здравствуйте, Pavel Dvorkin, Вы писали: PD>А кстати, о sprintf. Меня, как я помню, обвиняли в том. что возможно переполнение буфера. Не спорю, теоретически возможно. Но ведь и в этом операторе переполнение возможно PD>int nScreenArea = nScreenWidth * nScreenHeight;
Угу. Именно поэтому при дефолтных настройках компилятора C# такой код вызовет у тебя compile-time error.
А если ты попробуешь схитрить, и сделать, к примеру, вот так:
private int GetScreenArea(int w, int h)
{
return w*h;
}
,а в рантайме скормить свои суперпикселы в этот метод, то произойдет OverflowException. Никакой попытки сохранить отрицательное число для будущего использования не будет.
Впрочем, для тех, кто экономит такты, можно сделать и вот так:
// все пользователи этого метода торжественно клянуться
// передавать достаточно маленькие значения w и h!private int GetScreenArea(int w, int h)
{
return unchecked(w*h);
}
PD>Так вот, мой sprintf вызовет переполнение буфера. Обязательно вызовет. Но не раньше, чем этот пример сгенерирует integer overflow
Сгенерирует. Но, в отличие от переполнения буфера, у нас есть детерминированное поведение системы. А не Undefined Behavior, который в некоторых особенно злостных случаях дефайнят за нас злые хакеры, причем таким образом, что эта дефиниция приносит нам заметный ущерб. Не помнишь червячка под MS SQL, который года три назад положил полмира?
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали: PD>>А кстати, о sprintf. Меня, как я помню, обвиняли в том. что возможно переполнение буфера. Не спорю, теоретически возможно. Но ведь и в этом операторе переполнение возможно PD>>int nScreenArea = nScreenWidth * nScreenHeight; S>Угу. Именно поэтому при дефолтных настройках компилятора C# такой код вызовет у тебя compile-time error.
Я что-то не понял
static void Main(string[] args)
{
int nScreenWidth = 80000, nScreenHeight = 60000;
int nScreenArea = nScreenWidth * nScreenHeight;
}
Настройки не менял. Компилируется. Запускается. Дает неверный результат — 505032704.
Вот в таком виде дает exception
int nScreenWidth = 80000, nScreenHeight = 60000;
int nScreenArea;
checked
{
nScreenArea = nScreenWidth * nScreenHeight;
}
Т.е по умолчанию uncheked.
Или у меня с настройками что-то не то (вроде не трогал) ?
S>А если ты попробуешь схитрить, и сделать, к примеру, вот так: S>
S>private int GetScreenArea(int w, int h)
S>{
S> return w*h;
S>}
S>
S>,а в рантайме скормить свои суперпикселы в этот метод, то произойдет OverflowException. Никакой попытки сохранить отрицательное число для будущего использования не будет.
Здравствуйте, Дарней, Вы писали:
E>>Зато как же обломно после таких проектов формочки на JSP рисовать и SQL запросы сочинять! E>>Блин, словами не передать. E>>Зато антураж какой! Рефакторинг, юниттестинг, код ревью, баг трекинг, UML, XML, SQL,... память нынче не ресурс... давай, давай, сроки горят... память нынче не ресурс... давай, давай, все должно было работать еще вчера... память нынче не ресурс... Об эффективности программ
Да нет проблем. Привыкать на начальном этапе сложновато. Да и за всем этим антуражем очень глубоко запрятано главное -- программа должна работать. А то, по моему опыту, очень многие любят говорить с придыханием разные умные слова (вроде "паттернов", "рефакторингов" и пр.), а работающего кода от них можно и не дождаться. В общем, мусора всякого и бесполезного шума слишком много. В АСУТП-шных задачах его как-то поменьше, может быть потому, что гораздо меньше людей этими задачами занимаются.
Да и не заниматься тоже не проблема. Мне не понравилось, я ушел. Но здесь во многом повезло -- случай хороший представился.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Я что-то не понял
Виноват. Действительно, если не сказать компилятору /checked+, то по умолчанию чекинг отключен. Тем не менее, обработка подобных ситуаций встроена как на уровне платформы (соответствующие команды MSIL), так и на уровне компилятора С# (ключевые слова checked, unchecked и ключ командной строки /checked). Что прекрасно соответствует принципам, заложенным в основу дотнета. Здесь значительно сложнее добиться UB.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Допустим, что я понял это неправильно (хотя, честное слово, впервые об этом принципе я прочитал еще в 80-е годы, и в книге, которая к Unix не имела отношения. В таком случае будь добр объяснить, в чем неправильность моего понимания. Заявлять же — "ты неправ, и я не вижу смысла соприть на эту тему" — не есть аргумент.
Как я уже говорил, ведущие собаководы говорят — "читаемость и легкость расширения кода стоят превыше всего, в том числе и оптимальности по объему/производительности/любой иной"
отвечу заранее — нет, я не согласен с тем, что более простой код будет и более оптимальным. Совпадение одного с другим вполне возможно, но в большинстве случаев это вещи взаимоисключающие.
PD>Нет, я ее просто не держу. . Поэтому статистики не знаю. Триллиан падал за несколько лет раз 5, и то обычно при Windows shutdown (что-то они там не учли, видимо)
я тоже не держу — достала глюками и ненужными мне фичами, которые сжирают ресурсы. Поставил миранду — она у меня всего пару раз падала, но глючит все равно ничуть не меньше.
Д>>сразу вспоминается случай, когда разработчики решили, что длина серии паспорта не может быть больше 10 символов (может быть и не десять, не помню точно) Д>>А потом приехал парень из страны, где серия паспорта имела больше символов. И бедолага несколько месяцев ходил по инстанциям.
PD>Ну и что ? Это лишь говорит о том, что они неверно оценили максимальный размер, только и всего.
а они тоже думали, что оценили верно
PD>Вот давай так
PD>char szTotal[500]; PD>sprintf(szTotal,"%s %s", szFirstName, szLastName);
PD>Программа делается для России. Приведи ситуацию, в которой здесь возможен buffer overrun. Фамилию и имя, please , в студию.
фамилия очень простая — "Ивановвввввввввввввввввввввввввввввввв" (повторить нужное количество раз). Просто оператор заснул на клаве. Ах, такого не бывает, говоришь? Ну-ну.
Я уж не говорю о том, что это решение не только опасно, но еще и очень далеко от оптимума по производительности, которого тебе так сильно хотелось. Не догадываешься, почему? Рекомендую немного помедитировать над текстом sprintf
PD>Ну и что, опять-таки ? См. мой пример с nScreenArea. Может, оно когда-нибудь и грохнется, на 4ГПикс дисплее. Но не будешь же ставить под контроль все арифметические операции и на каждую из них писать try-catch из-за того, что при некорректно заданных операндах это может вызвать ошибку ? Или впрямь будешь писать везде так
как я уже говорил, твой пример к рассматриваемой ситуации с sprintf не имеет ни малейшего отношения. Поэтому смотреть тут особо и не на что.
PD>Нет. Не догадываюсь. Потому что любая ошибка может привести к любой наведенной ошибке. А если ты хочешь сказать, что при этом будет неопределенное поведение — так и при неправильных результатах будет то же, не только при выходе индекса.
разница в том, что ошибку переполнения можно обработать программно, ибо к порче сторонних данных она не ведет. Потертый стек — это однозначно полный трындец программе.
PD>А вообще основное различие между моей и твоей позицией ИМХО в том, что ты хорошо знаешь некоторые общепринятые принципы, но рассматриваешь их как догму, которую нельзя переступать, как сказал Sinclair, под страхом смертной казни. Я же считаю, что при определенных условиях может случиться так, что делать придется, нарушая многие общепринятые правила, если это нужно для решения задачи и другого выхода нет.
Эти самые "общепринятые принципы" были изучены мной на своей собственной шкуре, и на немаленьком количестве набитых шишек. Именно поэтому я говорю, что если ты вдруг подумал, что нужно нарушить один из них, потому что "это нужно для решения задачи и другого выхода нет" — значит, садись и думай еще раз.
Я в свое время тоже увлекался написанием мега-оптимизированных программ. Написал например для эксперимента дизассемблер для Z80, который целиком помещался в 1.5 килобайта. Но с тех пор я набил немало шишек, стал несколько мудрее и перестал заниматься подобной ерундой.
PD>В конце концов лучше написать работающую программу не по правилам, чем по правилам ничего не сделать.
А еще лучше — написать работающую программу, которая не будет использовать никаких грязных хаков. См также пример по sprintf выше
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Я что-то не понял S>Виноват. Действительно, если не сказать компилятору /checked+, то по умолчанию чекинг отключен. Тем не менее, обработка подобных ситуаций встроена как на уровне платформы (соответствующие команды MSIL), так и на уровне компилятора С# (ключевые слова checked, unchecked и ключ командной строки /checked). Что прекрасно соответствует принципам, заложенным в основу дотнета. Здесь значительно сложнее добиться UB.
Так что же. вот лично ТЫ будешь встраивать мое вычисление площади в checked или нет ? Кстати, тем самым ты получишь только то, что программа вылетит из-за exception, а это хоть и не UB, но радости все равно мало. Формулирую жестче — ты будешь каждую операцию ставить под try-catch ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>По второму кругу пойдем. Ведущие автомобилестроители говорят. что удобства разборки и сборки автомобиля важнее его характерстик.
мы осбуждали смысл того выражения, или тенденции в работе ведущих автомобилестроителей?
PD>И да, и нет... В большинстве — не согласен, а бывать — конечно, бывает.
я бы еще добавил — очень редко бывает
Д>>фамилия очень простая — "Ивановвввввввввввввввввввввввввввввввв" (повторить нужное количество раз). Просто оператор заснул на клаве. Ах, такого не бывает, говоришь?
PD>Нет, не бывает. Потому как в моей задаче данные брались из SQL сервера, там попросту не могло быть такого — места нет.
А потом данные переводят с SQL сервера в другое хранилище, а твой код не трогают, потому что "он же раньше нормально работал"
тот зонд про который я говорил в предыдущем постинге как раз из-за этого упал
PD>А не надо медитировать. Я sprintf просто для примера привел. Реально у меня была ConcatenateStrings собственной разработки. Черт ее. sprintf, знает, как она там по форматам преобразует
без разницы. если она использует ASCIIZ строки — значит, она по определению не оптимальна
PD>Ну и ставь себе try-catch на каждый оператор. Не много их найдется, которые в принципе не могли бы ошибку сгенерировать.
а на хрена ставить на КАЖДЫЙ оператор? Ты вообще знаком с принципами обработки исключений?
PD>Да зачем мне об этом опять думать ? Проект этот я давно сдал
вот с этого и надо было начинать. Проект сдал, а что с ним потом будет — это уже дело десятое.
PD>Вот ответь прямо на вопрос. Тебе предлагается проект. К нему жесткие требования по времени работы, не уложишься — не примут. Написать со всеми твоими проверками — знаешь сам, что не уложишься. Но знаешь и, что если займешься "написанием мега-оптимизированных программ" — уложишься. Ядерным реактором это не управляет, самолеты не водит, крах если раз в месяц произойдет — не смертельно, перезапустят. Твои действия ?
Проект я буду писать так, чтобы удовлетворял всем условиям. Предварительно заложив в оценку дополнительное время на тестирование и всевозможные проверки. Ты доволен?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Sinclair, Вы писали:
PD>>>Программа делается для России. Приведи ситуацию, в которой здесь возможен buffer overrun. Фамилию и имя, please , в студию. S>>Очень просто. Этот код вызывается из обработчика веб формы регистрации пользователей.
PD>Этот код НЕ вызывается из обработчика ВЕБ-форм. В этом случае так писать действительно не стоит. Этот код берет проверенные значения из БД, где для их хранения НЕ ОТВЕДЕНО 500 char. По-прежнему будешь утверждать ?
А кто помешает dba сделать alter table через пару лет после запуска твоего приложения? Причем предыдущие два alter table прошли на ура.
Впрочем, речь не о том. Речь о том, что ты предлагаешь полагаться на то, что данные уже проверены каким-то сторонним способом. По умолчанию так делать нельзя. Такой метод обязан быть private. Он должен быть обложен всеми мыслимыми ассертами, и документация обязана содержать четкое упоминание о том, как его можно вызывать.
PD>В общем, мы Вас не защищаем уже от багов, мы лишь обеспечиваем, чтобы Вы могли их найти, когда приложение рухнет
А не существует никакого средства защитить от багов. Есть средство защитить от UB. PD>ИМХО не стоит продолжать. Не договоримся. Разные позиции. Я готов с уважением относиться к твоей, но признавать ее как догму не могу.
Личное дело каждого.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel Dvorkin, Вы писали: PD>Так что же. вот лично ТЫ будешь встраивать мое вычисление площади в checked или нет ?
Если это код, который должен обеспечивать высокую надежность, то я просто скомпилирую его с /checked+. PD>Кстати, тем самым ты получишь только то, что программа вылетит из-за exception, а это хоть и не UB, но радости все равно мало.
Очень много. Вылет по exception — это детерминированное поведение. PD>Формулирую жестче — ты будешь каждую операцию ставить под try-catch ?
Нет конечно. А зачем? Что за бред? Сама идеология обработки исключений позволяет делать универсально применимый код. Я сделаю обработчик на достаточно высоком уровне, который попытается сделать что-то осмысленное.
И буду добавлять более низкоуровневые обработчики по мере необходимости.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
PD>>Ну и что ? Это лишь говорит о том, что они неверно оценили максимальный размер, только и всего.
PD>>Вот давай так
PD>>char szTotal[500]; PD>>sprintf(szTotal,"%s %s", szFirstName, szLastName);
PD>>Программа делается для России. Приведи ситуацию, в которой здесь возможен buffer overrun. Фамилию и имя, please , в студию. S>Очень просто. Этот код вызывается из обработчика веб формы регистрации пользователей. Злонамеренный пользователь вводит килобайт мусора. После чего твое CGI приложение делает core dump. Это называется уязвимость. S>Еще более злонамеренный пользователь вводит килобайт специального мусора, и твое CGI приложение вносит нужные изменения в системные настройки, а уже потом делает core dump. Это называется эксплойт. S>Продвинутый злонамеренный пользователь пишет плагин к известному сканеру сетей, который находит все инстансы твоего приложения в указанном IP — диапазоне. S>Таоя компания попадает в списки рассылки "смертельно опасные уязвимости", и ее продукт попадает в черный список. Это называется "банкротство".
Имхо, классики от программирования уже давно рекомендуют не доверять данным, приходящим к вам снаружи (а доверять только тем, что есть у вас в модуле, да и то с оглядкой). Тогда никаких страшилок с уязвимостями и эксплоитами можно не опасаться.
Что интересно, подобные проверки не лишены смысла и в управляемых средах.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Совершенно верно! Но, к сожалению, это была бы совсем другая программа.
И Павел не будет ее писать. Потому, что strlen — это медленная операция, а он-то как раз хотел сэкономить лишний проход по данным.
E>Что интересно, подобные проверки не лишены смысла и в управляемых средах.
Конечно не лишены. Более того, они принудительно встроены в эти управляемые среды. Там нельзя вызвать просто спринтф. Только в комплекте со strlen.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>А кто помешает dba сделать alter table через пару лет после запуска твоего приложения? Причем предыдущие два alter table прошли на ура.
И после этого alter table этот dba предусмотрит для русских имен 500 символов , а некий оператор ихз введет ? Заботиться об этом — все равно, что принимать меры по защите от землетрясений в Омске. Теоретически они везде возможны, а практически тут не было с мезозойской эры и еще одну эру не будет.
S>Впрочем, речь не о том. Речь о том, что ты предлагаешь полагаться на то, что данные уже проверены каким-то сторонним способом. По умолчанию так делать нельзя.
В общем случае — нельзя, согласен. И тот автор web-формы, кто допустил принятие 1000 символов в качестве фамилии — действительно, кандидат на увольнение.
Кстати, один забавный пример приведу. Во времена DOS было это. Ребята у нас разобрались с BOOT record дискеты и нашли, что ее код не проверяет что-то там в EBPB. Они это что-то заменили на 0 и вместо загрузки DOS падала с каким-то exception. Ты считаешь, что MS должна была защиту от тех, кому вздумается вручную BOOT-сектор править, у себя сделать ? Так ведь могли и в сектор не уложиться, а это, как сам понимаешь, в те времена фатально было — структуру FAT диска пришлось бы изменять.
>Такой метод обязан быть private. Он должен быть обложен всеми мыслимыми ассертами, и документация обязана содержать четкое упоминание о том, как его можно вызывать.
А он у меня не метод был. Он просто функция был, потому что (сейчас я тебя испугаю) весь проект не на С++, а на С делался. Приины мне неизвестны, но повлиять я не мог, потому что вошел в проект отнюдь не в его начали.
И была эта функция не то что private , а super private. Потому как описана она была у меня static, а в этот файл изменения имел право вносить только я . Из других частей проекта ее вызвать нельзя было никаким способом.
PD>>ИМХО не стоит продолжать. Не договоримся. Разные позиции. Я готов с уважением относиться к твоей, но признавать ее как догму не могу. S>Личное дело каждого.
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>По второму кругу пойдем. Ведущие автомобилестроители говорят. что удобства разборки и сборки автомобиля важнее его характерстик.
Д>мы осбуждали смысл того выражения, или тенденции в работе ведущих автомобилестроителей?
Ну судя по твоему предыдущему письму мы уже собаководов обсуждаем
PD>>И да, и нет... В большинстве — не согласен, а бывать — конечно, бывает.
Д>я бы еще добавил — очень редко бывает
Кто его знает... здесь статистика нужна, а не утверждения.
Д>А потом данные переводят с SQL сервера в другое хранилище, а твой код не трогают, потому что "он же раньше нормально работал"
Д>без разницы. если она использует ASCIIZ строки — значит, она по определению не оптимальна
Не понял. Ты имеешь в виду. что строка должна при себе всегда иметь размер, как в C# ? В Паскале, кстати, тоже имеет. Тут я с тобой не соглашусь — если надо, у меня каждая строка будет иметь этот размер (класс mystring напишу), а вот ты без этого оверхеда не обойдешься. И посему у меня моя фамилия будет занимать 8 байт, а у тебя — минимум 18 (7*2 из-за Юникода + 4 на длину, А кроме оптимизации по скорости, порой необходима оптимизация по памяти. Я могу и то и другое
Д>а на хрена ставить на КАЖДЫЙ оператор? Ты вообще знаком с принципами обработки исключений?
Немного знаком . А насчет "на КАЖДЫЙ" — так все же будешь ставить на мое вычисление площади или нет ? Да или нет ?
Д>вот с этого и надо было начинать. Проект сдал, а что с ним потом будет — это уже дело десятое.
Работает он. Вот и все. Ничего плохого с ним не было и не будет.
PD>>Вот ответь прямо на вопрос. Тебе предлагается проект. К нему жесткие требования по времени работы, не уложишься — не примут. Написать со всеми твоими проверками — знаешь сам, что не уложишься. Но знаешь и, что если займешься "написанием мега-оптимизированных программ" — уложишься. Ядерным реактором это не управляет, самолеты не водит, крах если раз в месяц произойдет — не смертельно, перезапустят. Твои действия ?
Д>Проект я буду писать так, чтобы удовлетворял всем условиям. Предварительно заложив в оценку дополнительное время на тестирование и всевозможные проверки. Ты доволен?
Не хочешь прямо ответить. Ладно, уточняю. Удовлетворить всем условиям — не получается. Без проверок нужное быстродействие дает машина 3GHz, а с проверками нужна на 6GHz, а ее нет. Если скорость будет меньше заказанной — не получишь ни копейки. Что будешь делать ?
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
S>Если это код, который должен обеспечивать высокую надежность, то я просто скомпилирую его с /checked+.
3 команды и 5 команд. Вот и получишь падение скорости.
PD>>Кстати, тем самым ты получишь только то, что программа вылетит из-за exception, а это хоть и не UB, но радости все равно мало. S>Очень много. Вылет по exception — это детерминированное поведение.
А радости все равно мало. Не работает ведь, как надо...
PD>>Формулирую жестче — ты будешь каждую операцию ставить под try-catch ? S>Нет конечно. А зачем? Что за бред? Сама идеология обработки исключений позволяет делать универсально применимый код. Я сделаю обработчик на достаточно высоком уровне, который попытается сделать что-то осмысленное.
Ну и что же осмысленное ты сделаешь в методе A.a, который вызывает B.b, который вызывает C.c, которая вычисляет nScreenArea ?
S>И буду добавлять более низкоуровневые обработчики по мере необходимости.
И куда же тут ты добавишь обработчик ? Имей в виду, там еще и другие потенциально опасные операторы есть. Напрмиер, там в ushort засылается высота человека (в см) путем сложения его роста с высотой его шляпы. Надо выяснить, пройдет через тоннель или не пройдет. А вдруг великан придет ростом в 33 метра ? Или шляпа у него с Монблан ? .
Если серьезнее, то ИМХО вы все просто немного зациклились на проверке все и вся. Все проверить — невозможно. И программа (если это не управление ядерным реактором) должна просто нормально обрабатывать 99.99... процента данных, а в остальном — как говорят американцы, поправка на I (на Иисуса т.е.)
Здравствуйте, eao197, Вы писали:
E>За исключением того, что программа у Павла могла быть написана с контролем входных данных:
Да нет, там никакой проверки не было. И sprintf там , конечно, тоже не было. Там было получение неких входных данных из разных мест (но надежных данных), их довольно непростое переформатирование и запись в выходной буфер со сдвигом в нем. Только и всего. В общем, на сериализацию похоже, только формат черт знает какой, и не в файл, а в буфер ОП. А размер этого буфера брался такой, что он заведомо был (раза в 2) больше, чем вообще может быть на белом свете . Вот и все.
делай, как хочешь. это проблема твоего начальства и твоих клиентов
Д>>без разницы. если она использует ASCIIZ строки — значит, она по определению не оптимальна
PD>Не понял. Ты имеешь в виду. что строка должна при себе всегда иметь размер, как в C# ? В Паскале, кстати, тоже имеет. Тут я с тобой не соглашусь — если надо, у меня каждая строка будет иметь этот размер (класс mystring напишу), а вот ты без этого оверхеда не обойдешься. И посему у меня моя фамилия будет занимать 8 байт, а у тебя — минимум 18 (7*2 из-за Юникода + 4 на длину, А кроме оптимизации по скорости, порой необходима оптимизация по памяти. Я могу и то и другое
а на практике получается ни того, ни другого, да еще и дырка в безопасности впридачу
PD>Немного знаком . А насчет "на КАЖДЫЙ" — так все же будешь ставить на мое вычисление площади или нет ? Да или нет ?
НЕТ
catch ставится там, где можно осмысленно обработать исключение. А не там, где оно выбрасывается.
PD>Работает он. Вот и все. Ничего плохого с ним не было и не будет.
будет. рано или поздно
PD>Не хочешь прямо ответить. Ладно, уточняю. Удовлетворить всем условиям — не получается. Без проверок нужное быстродействие дает машина 3GHz, а с проверками нужна на 6GHz, а ее нет. Если скорость будет меньше заказанной — не получишь ни копейки. Что будешь делать ?
я и ответил прямо. Если условия задачи действительно того потребуют, то я буду оптимизировать. Но оптимизировать "на всякий случай", как ты, я не буду
хотя иногда и хочется приходится душить это стремление в зародыше
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>3 команды и 5 команд. Вот и получишь падение скорости.
Рекомендую попробовать проверить реальную зависимость быстродействия от checked/unchecked. Не стоит судить по количесту команд. repne scasd еще помнишь?
PD>А радости все равно мало. Не работает ведь, как надо...
И как не надо — тоже не работает. PD>Ну и что же осмысленное ты сделаешь в методе A.a, который вызывает B.b, который вызывает C.c, которая вычисляет nScreenArea ?
Сохраню состояние и закончу обработку запроса. Может, это не screen area. Может, это программа, которая управляет выдачей ядохимикатов для участков полей. И твой вариант охрененно быстро недосыпет яду на сверхбольшой участок.
А мой будет устроен примерно так:
foreach(Zone z in ZonesToProcess)
{
try
{
double q = GetQuantityforZone(z); // где-то там в недрах есть checked вызов умножения. И очень-очень много другой работы.
OutgoingQueue.Add(new Pack(q, z));
} catch(Exception e)
{
log.Add("Не удалось выдать яду для объекта {0} : {1}", z, e);
}
}
DisplayLog(log);
И он насыплет яду всем, кому сможет. Независимо от того, произошел ли overflow или деление на ноль, или попытка откаститься не к тому типу. S>>И буду добавлять более низкоуровневые обработчики по мере необходимости. PD>И куда же тут ты добавишь обработчик ? Имей в виду, там еще и другие потенциально опасные операторы есть. Напрмиер, там в ushort засылается высота человека (в см) путем сложения его роста с высотой его шляпы. Надо выяснить, пройдет через тоннель или не пройдет. А вдруг великан придет ростом в 33 метра ? Или шляпа у него с Монблан ? .
Зачем бред-то городить? PD>Если серьезнее, то ИМХО вы все просто немного зациклились на проверке все и вся.
Это не мы такие. Это жизнь такая. PD> Все проверить — невозможно.
Никто и не предлагает проверять все. Но отказываться от проверок безопасности ради выигрыша в производительности, который еще и сильно преувеличен — бред.
PD>И программа (если это не управление ядерным реактором) должна просто нормально обрабатывать 99.99... процента данных, а в остальном — как говорят американцы, поправка на I (на Иисуса т.е.)
Ага. Пусть программа работает иногда. В коммерческом мире это называется альфа версией. Для справки: обычно есть еще две стадии готовности софта. Первой стадией обычно ограничиваются люди из академической среды, которых вопросы отказоустойчивости вообще не интересуют.
Просто я не могу принять такого подхода, "авось все будет нормально". В чем смысл тогда делать программу быстрой? Чтобы она быстрее упала при неправильном вводе?
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Ну судя по твоему предыдущему письму мы уже собаководов обсуждаем
Д>и у кого из нас нет чувства юмора?
У меня есть — я же смайлик поставил
Д>делай, как хочешь. это проблема твоего начальства и твоих клиентов
Клиенты у меня есть. Начальства нет.
Д>>>без разницы. если она использует ASCIIZ строки — значит, она по определению не оптимальна
PD>>Не понял. Ты имеешь в виду. что строка должна при себе всегда иметь размер, как в C# ? В Паскале, кстати, тоже имеет. Тут я с тобой не соглашусь — если надо, у меня каждая строка будет иметь этот размер (класс mystring напишу), а вот ты без этого оверхеда не обойдешься. И посему у меня моя фамилия будет занимать 8 байт, а у тебя — минимум 18 (7*2 из-за Юникода + 4 на длину, А кроме оптимизации по скорости, порой необходима оптимизация по памяти. Я могу и то и другое
Д>а на практике получается ни того, ни другого, да еще и дырка в безопасности впридачу
Да, бедные мы все. До появления Net писали себе char* и не знали. что не программы пишем, а только плодим "ни того, ни другого, да еще и дырка в безопасности впридачу"
PD>>Немного знаком . А насчет "на КАЖДЫЙ" — так все же будешь ставить на мое вычисление площади или нет ? Да или нет ?
Д>НЕТ Д>catch ставится там, где можно осмысленно обработать исключение. А не там, где оно выбрасывается.
Спасибо, просветил . Так скажи же, где осмысленно обработать исключение по вычислению площади 4Г пиксельного экрана ?
PD>>Работает он. Вот и все. Ничего плохого с ним не было и не будет.
Д>будет. рано или поздно
Угу. Я же говорил — как только 4Г пиксельные экраны появятся — так сразу и мой код полетит.
Д>я и ответил прямо. Если условия задачи действительно того потребуют, то я буду оптимизировать. Но оптимизировать "на всякий случай", как ты, я не буду
Здравствуйте! Из-за чего сыр-бор то разгорелся ? Из моего нежелания размер буфера контролировать. А почему я его контролировать не хотел — 2 дня объясняю , что времени нет. А оказывается. я это просто "на всякий случай" делал.
Д>хотя иногда и хочется приходится душить это стремление в зародыше
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>3 команды и 5 команд. Вот и получишь падение скорости. S>Рекомендую попробовать проверить реальную зависимость быстродействия от checked/unchecked. Не стоит судить по количесту команд. repne scasd еще помнишь?
Помню . Ладно, проверю
PD>>А радости все равно мало. Не работает ведь, как надо... S>И как не надо — тоже не работает.
Это , конечно, приятно — но все же не работает
PD>>И куда же тут ты добавишь обработчик ? Имей в виду, там еще и другие потенциально опасные операторы есть. Напрмиер, там в ushort засылается высота человека (в см) путем сложения его роста с высотой его шляпы. Надо выяснить, пройдет через тоннель или не пройдет. А вдруг великан придет ростом в 33 метра ? Или шляпа у него с Монблан ? . S>Зачем бред-то городить?
А ИМХО проверять такое — бред и есть.
PD>>Если серьезнее, то ИМХО вы все просто немного зациклились на проверке все и вся. S>Это не мы такие. Это жизнь такая.
Нет. Это не жизнь, это парадигма такая. Несмотря ни на какте реальные условия — предполагать, что может все что угодно произойти По деревянному мосту танк пойдет, великан ростом в 33 метра явится, экран будет в 4Г пикселей и т.д. Если нужна максимальная надежность — я за. А в текстовом редакторе — извините, я против того, чтобы ради этой надежности он в размерах в 2 раза увеличивался и работал медленно. Потому как меня как пользователя больше достает, что мне памяти не хватает. что ползет как черепаха и т.д. А упадет один раз в месяц этот текстовый редактор — ну и черт с ним. В крайнем случае, сделайте, как в Ворде — сохранение в temp файл раз в n минут.
PD>> Все проверить — невозможно. S>Никто и не предлагает проверять все. Но отказываться от проверок безопасности ради выигрыша в производительности, который еще и сильно преувеличен — бред.
Не надо насчет преувеличен. Даже в том примере, что я приводил. Если сделать как следует — надо длину всех строк определять + буфер выделять + очвобождать его. И это все — накладные расходы на копирование. Порядка 50% будет.
Только не говори мне, что в Net это делать не надо. Бесплатного ничего не бывает. Если длина строки внутри StringBuilder хранится — значит, кто-то и когда-то ее считал. А изменился он — пересчитывал. Чудес на свете не бывает.
PD>>И программа (если это не управление ядерным реактором) должна просто нормально обрабатывать 99.99... процента данных, а в остальном — как говорят американцы, поправка на I (на Иисуса т.е.) S>Ага. Пусть программа работает иногда. В коммерческом мире это называется альфа версией. Для справки: обычно есть еще две стадии готовности софта. Первой стадией обычно ограничиваются люди из академической среды, которых вопросы отказоустойчивости вообще не интересуют.
Да работает она, работает. Можешь быть спокоен, через нее уже не один миллион образцов прошел, и никто не жаловался. А насчет альфы и беты — не было унас ни того, ни другого. Потому как заказчик был один- единственный, но очень уж серьезный
S>Просто я не могу принять такого подхода, "авось все будет нормально". В чем смысл тогда делать программу быстрой? Чтобы она быстрее упала при неправильном вводе?
А в чем смысл доводить мои высказывания до абсурда ? Я разве предлагал не контролировать вообще ? При чем здесь неверный ввод, это к автору вводной формы вопрос. Не будет все нормально. И то. что может быть ненормально, надо проверять. Но строить сейсмостойкие здания в Омске не надо. Не будет здесь землетрясения. Просто не будет, понимаешь ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Да, бедные мы все. До появления Net писали себе char* и не знали. что не программы пишем, а только плодим "ни того, ни другого, да еще и дырка в безопасности впридачу"
таки да. Почитай ка списки уязвимостей в прогах на любом сайте, посвященном безопасности. Ты уверен, что твоих прог там еще нет?
PD>Спасибо, просветил . Так скажи же, где осмысленно обработать исключение по вычислению площади 4Г пиксельного экрана ?
вероятно, где-то около корневой функции. Хотя лучшее, что можно сделать в данном случае — это выдать сообщение об ошибке и закрыть прогу.
Ты все еще не видишь разницу по сравнению с потертым стеком?
PD>Здравствуйте! Из-за чего сыр-бор то разгорелся ? Из моего нежелания размер буфера контролировать. А почему я его контролировать не хотел — 2 дня объясняю , что времени нет. А оказывается. я это просто "на всякий случай" делал.
и опять таки да. Использовать std::string было бы куда надежнее, и возможно, даже эффективнее.
PD>Да бога ради. Только ICQ не пиши
ICQ — это слишком ничтожная цель. Мои коварные планы простираются куда дальше
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Да, бедные мы все. До появления Net писали себе char* и не знали. что не программы пишем, а только плодим "ни того, ни другого, да еще и дырка в безопасности впридачу"
Д>таки да. Почитай ка списки уязвимостей в прогах на любом сайте, посвященном безопасности. Ты уверен, что твоих прог там еще нет?
По определению их там быть не может. Причин 2
1. Безопасность там никому не нужна.
2. Об этой программе, кроме заказчика, никто не знает. Один был заказчик, но очень серьезный
PD>>Спасибо, просветил . Так скажи же, где осмысленно обработать исключение по вычислению площади 4Г пиксельного экрана ?
Д>вероятно, где-то около корневой функции. Хотя лучшее, что можно сделать в данном случае — это выдать сообщение об ошибке и закрыть прогу.
Д>Ты все еще не видишь разницу по сравнению с потертым стеком?
Слушай, не надо мне банальные вещи объяснять. Я тебя пркрасно понял — ты хочешь сказать, что в одном случае будет определенное поведение, хотя и не то, которое хотелось бы, а в другом — UB с потенциально непредсказуемыми последствиями. Так ведь ? Я это давно понял. Отвечаю еще раз : А) в моем случае никакого UB не будет, потому что, как сказал Чехов, этого не может быть, потому что этого не может быть никогда и B) если бы даже оно могло произойти (не в моей программе, в аналогичной один раз в месяц, то беды в этом большой нет, потому как это не та ситуация, когда падение программы может привести к фатальным последствиям.
PD>>Здравствуйте! Из-за чего сыр-бор то разгорелся ? Из моего нежелания размер буфера контролировать. А почему я его контролировать не хотел — 2 дня объясняю , что времени нет. А оказывается. я это просто "на всякий случай" делал.
Д>и опять таки да. Использовать std::string было бы куда надежнее, и возможно, даже эффективнее.
Эффективнее уж точно !
PD>>Да бога ради. Только ICQ не пиши
Д>ICQ — это слишком ничтожная цель. Мои коварные планы простираются куда дальше
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>2. Об этой программе, кроме заказчика, никто не знает. Один был заказчик, но очень серьезный
давай может еще пиписками померяемся?
ну как ребенок, честное слово
PD>Слушай, не надо мне банальные вещи объяснять. Я тебя пркрасно понял — ты хочешь сказать, что в одном случае будет определенное поведение, хотя и не то, которое хотелось бы, а в другом — UB с потенциально непредсказуемыми последствиями. Так ведь ?
Ну что ж — очень рад, что ты наконец это понял.
PD>Успехов!
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>2. Об этой программе, кроме заказчика, никто не знает. Один был заказчик, но очень серьезный
Д>давай может еще пиписками померяемся? Д>ну как ребенок, честное слово
S>Решил помочь с примером: S> Есть в физике понятие материальная точка — это точка, размерами которой можно пренебречь, соответсвенно есть просто точка — её размерами пренебрегать не стоит.
S>Соответсвенно, в Вашем коде, если я правильно понял спринтф — материальная точка .
Вообще-то, насколько я помню, у просто точки размеров нет вообще. Если ты имел в виду тело — тогда да.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, srggal, Вы писали:
S>>Решил помочь с примером: S>> Есть в физике понятие материальная точка — это тело, размерами которого можно пренебречь, соответсвенно есть просто точка — её размерами пренебрегать не стоит.
PD>Вообще-то, насколько я помню, у просто точки размеров нет вообще. Если ты имел в виду тело — тогда да.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ай-яй-яй!!! Как же это я так оплошал . Говорил, что , мол, нет времени на длину строки, проход мол, а ведь strcat — тоже проход, а оказывается, это быстрее, чем мой однопроходной код! Вот и делай после этого заявления про оптимизацию
PD>Не так уж много, верно, процентов 10-15. Только вот здесь всего 2 строки конкатенируются, а у меня их было обычно 5-10.
ну раз уж пошла такая пьянка — сделаем условия более близкими к твоей задаче, как ты ее описываешь
то есть, вариант с strcat медленнее более чем в два раза
и здесь еще только четыре строки — при росте количества строк и их длины разрыв увеличится еще больше
поздравляю вас, товарищ, с выдающимися успехами в области оптимизации!
Здравствуйте, WolfHound, Вы писали:
WH> StringBuilder sb = new StringBuilder(); WH>... WH> for (int i = 0; i < 100000; ++i) WH> { WH> sb.Length = 0; WH> sb.Append(szFirstName); WH> sb.Append(szLastName); WH> } WH>[/c#] WH>0,04493758
Так не пойдет. Чтобы было эквивалентно С++ варианту нужно ещё из StringBuilder получить String.
WH>Оптимизированый вариант на C# получается на уровне С++ Ну чуть медленнее. WH>Кстати для корректности теста перепиши свои на wchar_t.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, alexeiz, Вы писали:
A>>Здравствуйте, GlebZ, Вы писали:
GZ>>>Здравствуйте, alexeiz, Вы писали:
A>>>>Так не пойдет. Чтобы было эквивалентно С++ варианту нужно ещё из StringBuilder получить String. GZ>>>Почему?
A>>В C++ версии на входе две строки на выходе одна. В C# — на выходе какой-то буфер (StringBuilder то есть). Чтобы его использовать как строку, нужно еще совершить преобразование. GZ>Неа. На выходе один и тот же буфер содержащий строку. 100 байт стека. StringBuilder.ToString() — это не преобразование строки, а возврат буфера в виде строки. То есть все абсолютно аналогично.
Только с той разницей, что чтобы преобразовать буфер в строку в C, не нужно делать ничего. Например, нам надо передать строку после конкатенации в функцию foo(char*). В C — просто передаём этот самый буфер. В C# функция будет выглядеть как foo(string), и чтобы передать туда результирующую строку нам нужно сначала преобразовать StringBuffer в String.
GZ>Другой вопрос в Net с одним и тем же буфером создавать две строки нельзя. Поэтому аналогичным будет создание всегда новой строки.
В этом тесте используется конкретная возможность C — создание строк на стеке с прямой целью, чтобы показать приемущество этого языка по сравнению с C#.
Здравствуйте, GlebZ, Вы писали:
ПК>>С такими ошибками в C++ шаблоны могут помочь бороться. GZ>Заметка из жизни. Если у программиста проблемы с ДНК, то C# многое прощает, а вот шаблоны в С++ многое усугубляют.
Не. Если проблемы в ДНК, то этому человеку Шарп уже не поможит. Но несоменно что в виду типобезопасности и малограбельности Шарп делает более защищенными тех кто волею судеб вынужден рабоатать в одной команде с наситями проблемных ДНК.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, GlebZ, Вы писали:
GZ>Не думал что подобная заметка из жизни вызывет флейм о вилках и детской посуде.
Хэх. Не знашь ты жизни. Скажу чесно я точно знал реакцию. Она просто не могла быть другой.
И дело тут в психологии. Людям больше всего ненравится признавать свои ошибки и недостатки в любимых вещах. Причем если это не делать, то со временем формируется те самые мании и фобии.
GZ>Так что если говорить о промышленных языках, то я бы сказал что они есть компромисс — помочь первым, и не мешать вторым.
Любое достойное дело и или вещь является компромисом. Бескомромисной может быть только вера и преданность.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Дарней, Вы писали:
Д>то есть, вариант с strcat медленнее более чем в два раза Д>и здесь еще только четыре строки — при росте количества строк и их длины разрыв увеличится еще больше Д>поздравляю вас, товарищ, с выдающимися успехами в области оптимизации!
Батенька, вы бы хоть читали внимательно. Я и писал-то, что strcat медленнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Батенька, вы бы хоть читали внимательно. Я и писал-то, что strcat медленнее.
вот я и читал твои высказывания о том, что на твою программу накладывались жесткие ограничения по времени работы, из-за чего ты использовал в своем коде небезопасные конструкции
небольшой эксперимент показал, что лишенный проблем с безопасностью вариант с использованием std::string еще и работает куда быстрее, чем твой вариант — ценой потери небольшого количества памяти из тех гигабайтов, которые были у тебя в наличии, но которые ты не использовал
Вот мне и стало интересно — чего ты в конце концов хотел добиться своими "оптимизациями"?
Здравствуйте, Pavel Dvorkin, Вы писали:
>Разумеется, эффективности внимание перестали уделять не везде. Для тех >программ, которые и сейчас работают на пределе возможностей машины, за >эффективность по-прежнему борются, да еще как, иначе ведь работать вообще >не будет. Ну а там, где для предела далеко — чего это мы будем лишний >десяток Мбайт экономить ? Пусть пользователь память докупит, она нынче >дешевая!
Переходи в gamedev, и будет тебе счастье...
Правильно работающая программа — просто частный случай Undefined Behavior
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А зачем ? Надо будет — перепишу. А пока мне и так хорошо — там, как я знаю, только 0-127. И незачем мне делать 50% оверхед. Я могу и не переписывать. А вот ты можешь на ASCII переписать ?
С некоторым извратом, но можем. Мы по-прежнему можем оперировать массивами байт (только, в отличие от плюсов, безопасно), и приводить их к строке только там, где нужно. Нет принципиальной проблемы завести пару классов CompactString/CompactStringBuilder. Они будут работать не слишком хуже стандартных аналогов. Но значительного выигрыша от этого не получится, по крайней мере до тех пор, пока мы не работаем с очень большими объемами.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>А зачем ? Надо будет — перепишу. А пока мне и так хорошо — там, как я знаю, только 0-127. И незачем мне делать 50% оверхед. Я могу и не переписывать. А вот ты можешь на ASCII переписать ? S>С некоторым извратом, но можем. Мы по-прежнему можем оперировать массивами байт (только, в отличие от плюсов, безопасно), и приводить их к строке только там, где нужно. Нет принципиальной проблемы завести пару классов CompactString/CompactStringBuilder. Они будут работать не слишком хуже стандартных аналогов. Но значительного выигрыша от этого не получится, по крайней мере до тех пор, пока мы не работаем с очень большими объемами.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, alexeiz, Вы писали:
A>>Только с той разницей, что чтобы преобразовать буфер в строку в C, не нужно делать ничего. Например, нам надо передать строку после конкатенации в функцию foo(char*). В C — просто передаём этот самый буфер. В C# функция будет выглядеть как foo(string), и чтобы передать туда результирующую строку нам нужно сначала преобразовать StringBuffer в String. S>Ты сильно преувеличиваешь стомость этой операции. Посмотри исходники StringBuilder.ToString() рефлектором.
Я бы тебе посоветовал вставить эту операцию в тест и посмотреть на то, как увеличится время. Уверяю тебя, будет очень близко к простой конкатенации строк оператором сложения. Так что мы ничего не выигрываем применяя StringBuilder для конкатенации двух строк, что собственно абсолютно не удивительно.
S>З.Ы. Не все, что занимает меньше асм-команд, тратит меньше тактов S>З.З.Ы. Не все вызовы одинаково дороги.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, alexeiz, Вы писали:
GZ>>>Другой вопрос в Net с одним и тем же буфером создавать две строки нельзя. Поэтому аналогичным будет создание всегда новой строки. A>>В этом тесте используется конкретная возможность C — создание строк на стеке с прямой целью, чтобы показать приемущество этого языка по сравнению с C#. GZ>Да нет тут никакого преимущества. Преимущество имеет значительно более большее значение чем просто производительность. Про один буфер я прогнал. Можно и в одном буфере с помощью unsafe кода. Только использование unsafe дает большую производительность для конкретной задачи, но меньшую эффективность. Потому как нафигарить можно не хуже чем в C++. GZ>Во вторых — это не создание строк, а заполнение буфера строками в цикле. Разница в этих терминах есть и существенная. GZ>В третьих, если ты не получал ошибок когда ты выходишь за границы массива, значит ты никогда не писал на C. Так что данное упражнение отнюдь не показывает эффективность языка. Оно больше показывает его недостатки.
Приемущество языка С заключается в том, что он позволяет (не требует а позволяет) спуститься на уровень железа. Для С# это очень и очень ограничено. Все размышления о выходе за границы массива идут лесом. Это просто отдельный разговор.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ты бы хоть внимательно посмотрел, что ты со string сделал PD>Это, между прочим, вызов конструктора. Который при этом вычисляет длину (поле string::_MySize) и теперь эта длина используется в операциях = и +=. А вызываешь этот конструктор ты один раз, а не 10000000 раз. Вот поставь так
я прекрасно понимаю, что я сделал со string
длина каждой строки и должна вычисляться один-единственный раз, если тебя хоть сколько-то заботит производительность
точнее — там, где она считывается из источника.
Здравствуйте, alexeiz, Вы писали:
A>Я посмотрю, как ты будешь со строками в unsafe коде работать. То, что ты можешь работать с памятью и указателями, для строк не имеет ни малейшего значения.
Можно-можно. Никто не запретит ему в ансейф моде работать с байтами, и конвертить к строке от случая к случаю.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alexeiz, Вы писали:
S>>Ты сильно преувеличиваешь стомость этой операции. Посмотри исходники StringBuilder.ToString() рефлектором.
A>Я бы тебе посоветовал вставить эту операцию в тест и посмотреть на то, как увеличится время. Уверяю тебя, будет очень близко к простой конкатенации строк оператором сложения. Так что мы ничего не выигрываем применяя StringBuilder для конкатенации двух строк, что собственно абсолютно не удивительно.
Все зависит от того, как вставлять. StringBuilder.ToString — операция более интересная чем просто возврат буфера как стринг. Он будет возвращать только один раз. На второй вызов будет сгенерена другая строка. Это было введено в 1.1 как требование защиты. Как я уже говорил, строку можно изменять через unsafe. Можно туда нагенерить и очень плохой код(например переполнение стека для креша или взлома системы ). В старой версии при повторном ToString возвращалась ссылка на одну и ту же строку, и при ее изменении изменялись все связанные строки. Так что смотря как вставишь, и в какую версию Net Framework. А защищенный Framework мне кажется значительно лучше, чем беззащитный но быстрый.
Здравствуйте, alexeiz, Вы писали:
A>Я посмотрю, как ты будешь со строками в unsafe коде работать.
Легко. Пишу примерно, возможны (или скорее всего будут) ошибки. Unsafe не часто пишешь.
//поскольку в севом варианте такое есть(непонятно зачем) то и здесь сделаю.public static unsafe void SetLength(string s, int length)
{
fixed(char *p = s)
{
int *pi = (int *)p;
if (length<0 || length > pi[-2])
throw( new ArgumentOutOfRangeException("Хоть какая-то защита :) ") );
pi[-1] = length;
p[length] = '\0';
}
}
public static unsafe void Concat(string dest, string source1, string source2)
{
int slen1=source1.Length;
int slen2=source2.Length;
SetLength(source1.Length, source2.Length);
fixed(char* pSource1)
{
fixed(char* pSource2)
{
fixed(char* pDest)
{
for(int i=0;i<source1.Length;i++)
pDesc[i]=*pSource1;
for(;i<source2.Length;i++)
pDesc[i]=*pSource2;
}
}
}
}
static usafe void MyProgram.Main()
{
const n=1000000;
string stringBuf=new String('\0', 100);
for(int i=0;i<n;i++)
Concat(stringBuf, "bla", "bla-bla");
}
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Ты бы хоть внимательно посмотрел, что ты со string сделал PD>>Это, между прочим, вызов конструктора. Который при этом вычисляет длину (поле string::_MySize) и теперь эта длина используется в операциях = и +=. А вызываешь этот конструктор ты один раз, а не 10000000 раз. Вот поставь так
Д>я прекрасно понимаю, что я сделал со string Д>длина каждой строки и должна вычисляться один-единственный раз, если тебя хоть сколько-то заботит производительность Д>точнее — там, где она считывается из источника.
А цикл, между прочим, выполняется 10000000 раз. Просто для того, чтобы время можно было замерить. А в реальной работе если он и выполнится 10000000 раз, то уж не с одними и теми же входными строками в любом случае Так что уж будь добр свой пример переделать таким образом, чтобы 10000000 он хотя бы имитировал, что строки у него новые.
Мне это — ничего не стоит
[code]
char szTotal[500];
char * pszTmpTotal,*pszTmpFirst, *pszTmpLast;
for(size_t i=0;i<10000000;++i)
{
char* szFirstName = куда надо 1
char* szLastName = куда надо 2
char* astr = куда надо 3
char* bstr = куда надо 4
// и во всех предыдущих 4 операциях скорость от того, что есть "куда надо i" не зависит и каждый раз эти "куда надо i" могут вполне быть различными. Или адресом одного и того же буфера, но содержащего другие данные
Здравствуйте, GlebZ, Вы писали: GZ>В старой версии при повторном ToString возвращалась ссылка на одну и ту же строку, и при ее изменении изменялись все связанные строки
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, GlebZ, Вы писали: GZ>>В старой версии при повторном ToString возвращалась ссылка на одну и ту же строку, и при ее изменении изменялись все связанные строки
ANS>Фига се баг! Не ожидал.
Да вообще-то багом это назвать трудно. Строка — сущность unmutable. Единственное исключение — unsafe код(и то, надо знать как ). В большинстве случаев программист знает что делает передавая строку(а за пределы домена Net она передается только в виде копии), но в случае с StringBuilder.ToString — это происходит неявно. Что и посчитали неправильным.
Здравствуйте, GlebZ, Вы писали:
GZ>>>В старой версии при повторном ToString возвращалась ссылка на одну и ту же строку, и при ее изменении изменялись все связанные строки
ANS>>Фига се баг! Не ожидал. GZ>Да вообще-то багом это назвать трудно. Строка — сущность unmutable. Единственное исключение — unsafe код(и то, надо знать как ). В большинстве случаев программист знает что делает передавая строку(а за пределы домена Net она передается только в виде копии), но в случае с StringBuilder.ToString — это происходит неявно. Что и посчитали неправильным.
Не совсем понял. Я так понял, что при дозаписи в StringBuffer меняется полученная раннее строка. Я не правильно понял суть ошибки?
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>>Не совсем понял. Я так понял, что при дозаписи в StringBuffer меняется полученная раннее строка. Я не правильно понял суть ошибки? GZ>Да. Неправильно. При любом дополнительном изменении StringBuilder после вызова ToString() выделяется новый буфер для изменений. Проблема примерно такая:
Здравствуйте, srggal, Вы писали:
S>Хоть Вы и читтер уважаемый, ан все равно приятно увидеть Думмера, ( поглаживая свой БФЖ ), и вспоминать как БФЖ рулит на 7мом уровне в дедматч. Эххх.
Думмер с БФГ имеет конкретное сокращенное наименование — ламер.
Помнится я как-то отучил своих коллег использовать ту самую БФГ на модифицированном 7-ом уровне (из Дума 2). Сделал это очень просто... взял ее и бегал по кругу собирая патроны и долбя об стенку. То ли дело базука. От это было оружие.
Ну, да завязывайте с думом. Тут это офотоп.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, alexeiz, Вы писали:
A>Так не пойдет. Чтобы было эквивалентно С++ варианту нужно ещё из StringBuilder получить String.
А зачем? Какой вообще смысл у этого теста? В реальной жизни ничего подобного не будет.
Создайте реальный тест который делает что-то осмысленное, и тогда измеряйте результат. А так это просто бред натуральный получается.
ЗЫ
А за работу со строками на уровне указателей вообще увольнять нужно.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, alexeiz, Вы писали:
A>Только с той разницей, что чтобы преобразовать буфер в строку в C, не нужно делать ничего. Например, нам надо передать строку после конкатенации в функцию foo(char*). В C — просто передаём этот самый буфер. В C# функция будет выглядеть как foo(string), и чтобы передать туда результирующую строку нам нужно сначала преобразовать StringBuffer в String.
Блни, а что такое "просто строка"? Это кусок памяти? А где его разместить? Вот размести его в плюсовой куче и сравни скорость. Уверю тебя плюсы будут в полной заднице.
A>В этом тесте используется конкретная возможность C — создание строк на стеке с прямой целью, чтобы показать приемущество этого языка по сравнению с C#.
Вот только на C# можно делать тоже самое. А не делают потому-что это каменный век.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, alexeiz, Вы писали:
A>Я бы тебе посоветовал вставить эту операцию в тест и посмотреть на то, как увеличится время. Уверяю тебя, будет очень близко к простой конкатенации строк оператором сложения. Так что мы ничего не выигрываем применяя StringBuilder для конкатенации двух строк, что собственно абсолютно не удивительно.
А ты вствь в код С++-теста код создания отдельных экземпляров строк. Уверяю тебя, что создать их в стеке у тебя не удастся. Останется только создавать строки в хипе. И если память не кончится, тормозить этот тест будет так, что Шарпу и не снилось.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
>> Излишней является любая оптимизация, которая не направлена на изменение ситуации, при которой система не способна уложиться в определенные в проекте временные рамки на том оборудовании, для работы на котором она предназначена.
ПК>Только та, которая стоит дополнительного времени при разработке.
И та что усложняет код.
А теперь назови оптимизации не далеющие того или другого.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Не любая. Например, есть выбор: написать сортировку "пузырьком" или использовать библиотечную std::sort. Первое делать дольше и в большинстве случаев работать будет медленнее, чем второе.
Это подмена понятий. Оптимизация — это, например, переписывание пузырька на быструю сортировку. А использование библиотечной функции оптимизацией не является. Это разумно сделать даже если речь о производительности не идет.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, McSeem2, Вы писали:
MS>Да, но есть случаи, когда этот "пузырек" побьет std::sort в разы или даже десятки раз (на почти отсортированных массивах). В моей практике такой случай был, причем очень хитрый. В 99% случаев данные были отсортированы. В 0.9 процентов случаев — почти отсортированы. В 0.1% случаев — практически в беспорядке. Решение таково: пишем bubble sort (да, именно ее). Данная сортировка, являясь "наитупейшей" обладает важным свойством — мы можем контролировать, насколько нам удалось продвинуться и сколько мы сделали перестановок. В 99% случаев она срабатывала без единой перестановки. Но как только количество перестановок превышало некий предел (подобранный эмпирически), мы все бросали и отдавали на съедение quick sort. Это эмпирическое знание позволило ускорить некий процесс обработки данных более чем вдвое, по сравнению с просто вызовом std::sort().
Не вспомнишь... эта константа была 2 или 3?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, gear nuke, Вы писали:
GN>Когда-то спросил старого программера, как писать оптимальные программы. Я то думал, вопрос с подковыркой (оптимизировать по скорости или по размеру можно). А он ответил просто: "упрощай их".
Это плохой совет, так как неполный. "Простота" — понятие перегруженое. Если брать простые алгоритмы, то обычно они являются куда менее эффективными.
Но есть другая простота. Это простота восприятия. Добиться ее можно грамотно подбирая и исползуя абстракции.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Хотел я в исходном постинге напомнить про один принцип. Потом решил, что введет ненужную игривость
PD>KISS — Keep It Simple, Stupid!
Помнится один авторитетный товаришь к этот прицип формулировал несколько иначе "Все должно быть простым, настолько простым насколько это возможно — но не проще.". И я с ним согласен.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Это плохой совет, так как неполный. "Простота" — понятие перегруженое. Если брать простые алгоритмы, то обычно они являются куда менее эффективными.
Алгоритмы тут не причём. Упрощать нужно не их самих, а их реализацию.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, VladD2,
GN>>Когда-то спросил старого программера, как писать оптимальные программы. Я то думал, вопрос с подковыркой (оптимизировать по скорости или по размеру можно). А он ответил просто: "упрощай их".
VD>Это плохой совет, так как неполный. "Простота" — понятие перегруженое. Если брать простые алгоритмы, то обычно они являются куда менее эффективными.
VD>Но есть другая простота. Это простота восприятия. Добиться ее можно грамотно подбирая и исползуя абстракции.
Мне кажется, он имел ввиду упрощение на самом верхнем уровне. В рамках целой задачи простой или сложный алго — лишь элементарное звено, упрощая его можно задачу и не упростить. В то же время — абстракция суть дополнительное элементарное звено, и слишком большое их количество может усложнить задачу.
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
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Нет. Я просто удивляюсь, что эти ситсемы используют алгоритмы, в которых вместо одного прохода требуется 3, вместо одного блока памяти — 2 и т.д. И мне говорят, что при этом повышается читабельность и легче сопровождение и т.д. Вот это я не понимаю и не принимаю.
VD>Слушай, брось программировать. Береги нервы.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, alexeiz, Вы писали:
A>>Я посмотрю, как ты будешь со строками в unsafe коде работать. GZ>Легко. Пишу примерно, возможны (или скорее всего будут) ошибки. Unsafe не часто пишешь.
<ужасный код пропущен>
Я даже не знаю, что бы я сделал такое с человеком, написавшим подобный код. Одно ясно: он явно напрашивается на неприятности (мягко говоря).
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, srggal, Вы писали:
S>>Хоть Вы и читтер уважаемый, ан все равно приятно увидеть Думмера, ( поглаживая свой БФЖ ), и вспоминать как БФЖ рулит на 7мом уровне в дедматч. Эххх.
VD>Думмер с БФГ имеет конкретное сокращенное наименование — ламер.
VD>Помнится я как-то отучил своих коллег использовать ту самую БФГ на модифицированном 7-ом уровне (из Дума 2). Сделал это очень просто... взял ее и бегал по кругу собирая патроны и долбя об стенку. То ли дело базука. От это было оружие.
Ламмеров — отучил бы, а я — выходил бы на круг по которому Вы бегаете с пистолетом, и не сделав бы ни одного выстрела смотрел бы как тело врага, возможно Ваше, оседает на пол
БФГ в Думе2 — надо уметь пользоваться, не нужно стрелять им в голову, выстрел в стену и стрейф без иззменения угла, после выстрела — и все что видит владелец БФЖ, пока кипит на стене выстрел ( в том числе и за стеной ), — все умирает.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, srggal, Вы писали:
S>>Ламмеров — отучил бы, а я — выходил бы на круг по которому Вы бегаете с пистолетом, и не сделав бы ни одного выстрела смотрел бы как тело врага, возможно Ваше, оседает на пол
VD>Ну, то что ты трепачь я уже давно понял.
No comment
VD>Это безграмотное обяснение. Реальное обяснение намного сложнее. VD>Стрэйфить никуда не нужно. Просто при попадании снаряда ВБГ в стену или оппонента проводился мысленный веер состоящий из 43 (за точное число не ручаю) "лучей смерти". Центр веера проводися от туловища стрелвшего по напавлениб к месту поподания. По этому совершенно все равно куда ты смотришь или как ты сртэйфишся. Можно было отвернусться и ждать пока все перадохнут. Вот только с удалением лучи расходятся и наносят все меньше и меньше урона. Да и в узком месте пучок не столь широк чтобы можно было безнаказанно убивать все на своем пути. 100%-ная смерь наступала только при прямом попадании или на небольшом растоянии и малом угле. Плюс к тому огромный лаг при выстреле и характерный звук. Собствнно это позволяло очень многих любителей семерки класть банальным ружьем. Главное было вовремя зайти к ним за спину.
43 не 43 веер — не веер, в детали не вникал, бегал с зажатым шифтом и боком около стен (Если Вам это о чем-то говорит, кстати, если говорит — формулы приводить не нужно )
1 на 1 трудно зайти щаспину бегая по внешнему кругу в 7м уровне Тем более стреялять из RL ShGun рулит там беспредельно ИМХО.
По попоаду смерти, достаточно было попасть в угол ограждения внутреннего круга и выйти на внешний. если
Было замечено, что вращение вокруг своей оси не способствует 100% смерти противника, описанное мной поведение способствует
Лаг — не лаг, но для бегающего по внешнему кругу это было как раз самое то
Для тех кто вбегает на внутренний круг, или выходит из ограждения внутреннего круга — РЛ, Война на шифтах в центре — Шотган Все это я говорю о Дуэли
ЗЫ Жаль что, теоритически хорошо подкованный думмер — превратился в человека который не любит незнакомое, и имеет претензии к тому, чем не владеет Пописал на С++... долго думал :)
Здравствуйте, srggal, Вы писали:
S>ЗЫ Жаль что, теоритически хорошо подкованный думмер — превратился в человека который не любит незнакомое, и имеет претензии к тому, чем не владеет Пописал на С++... долго думал :)
Ты видимо неадекватно воспринимашь реальность. Я не теоритически подкованный думер. Я просто когда-то очень недурно играл в эту игру. И мне не нужно рассказывать о ней. Собственно точно так же я довольно не дурно и уж точно довольно долго (около 10 лет) программировал на С++. Шаблоны, правда, в те времена были слабее, но сути дела это не менят. Так что можшь не сомневаться владею я им не хуже чем ты.
Так что твои безопеляционные предположения "не любит незнакомое", "имеет претензии к тому, чем не владеет" оставь при себе. Учись воспринимать себя адекватно. Ты не один в этом мире что-то видел, и что-то знашь. Всегда найдутся люди которые видили больше тебя и знают по более.
Например, я не нелюблю незнакомое и не имею претензии к тому в чем не понимаю. Я критикую то что прекрасно понимаю и знаком с тем что, например, тебе не знакомо. От того собственно и кртикую. С++ протух и продолжает тухнуть с каждым годом. Выход нового стандарта затягивается. Да и надежды на реальные перемены в нем тоже таят на глазах. Вот на это я собственно и обращаю внимание.
S>ЗЫЗЫ В любом случае — ДУМ БЫЛ ХОРОШ с тех пор больше небыло таких радикальных вещей S>И жаль, что iddqd уже ничего не говорит большинству людей
Он так же хорош как плюсы, то есть в прошом. Ку3 оказался объективно более играбельным. Хотя конечно эффект первой любви заставляет многих воспринимать его субъективно. Мы вот долго в думе души не чаяли. Уже вышли и Ку1-2, и Анрыл, а мы все равно продолжали резаться по вечерам в дум. Но вот когда вышел Ку3, то даже скептики через некоторое время поняли, что дум пора списывать. Думаю, что такой большой срок жизни дума в нашей конторе был обусловлен очень хорошей переделкой того самого 7-го уровня. Думаю, на нем меня и сейчас никто не порвет. Хотя прошло уже лет 7 как мы в него не играем. Ну, да детство все это. Я уже и в современные то игры не играю. Не то что в дум.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, gear nuke, Вы писали:
VD>>Но есть другая простота. Это простота восприятия. Добиться ее можно грамотно подбирая и исползуя абстракции.
GN>Мне кажется, он имел ввиду упрощение на самом верхнем уровне. В рамках целой задачи простой или сложный алго — лишь элементарное звено, упрощая его можно задачу и не упростить. В то же время — абстракция суть дополнительное элементарное звено, и слишком большое их количество может усложнить задачу.
Прочитай внимательно выделенные слова.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>
VD>Ты видимо неадекватно воспринимашь реальность. Я не теоритически подкованный думер. Я просто когда-то очень недурно играл в эту игру. И мне не нужно рассказывать о ней. Собственно точно так же я довольно не дурно и уж точно довольно долго (около 10 лет) программировал на С++. Шаблоны, правда, в те времена были слабее, но сути дела это не менят. Так что можшь не сомневаться владею я им не хуже чем ты.
VD>Так что твои безопеляционные предположения "не любит незнакомое", "имеет претензии к тому, чем не владеет" оставь при себе. Учись воспринимать себя адекватно. Ты не один в этом мире что-то видел, и что-то знашь. Всегда найдутся люди которые видили больше тебя и знают по более.
VD>Например, я не нелюблю незнакомое и не имею претензии к тому в чем не понимаю. Я критикую то что прекрасно понимаю и знаком с тем что, например, тебе не знакомо. От того собственно и кртикую. С++ протух и продолжает тухнуть с каждым годом. Выход нового стандарта затягивается. Да и надежды на реальные перемены в нем тоже таят на глазах. Вот на это я собственно и обращаю внимание.
Из Ваших постов, следует обратный вывод. Дискутировать не буду.
S>>ЗЫЗЫ В любом случае — ДУМ БЫЛ ХОРОШ с тех пор больше небыло таких радикальных вещей S>>И жаль, что iddqd уже ничего не говорит большинству людей
VD>Он так же хорош как плюсы, то есть в прошом. Ку3 оказался объективно более играбельным. Хотя конечно эффект первой любви заставляет многих воспринимать его субъективно. Мы вот долго в думе души не чаяли. Уже вышли и Ку1-2, и Анрыл, а мы все равно продолжали резаться по вечерам в дум. Но вот когда вышел Ку3, то даже скептики через некоторое время поняли, что дум пора списывать. Думаю, что такой большой срок жизни дума в нашей конторе был обусловлен очень хорошей переделкой того самого 7-го уровня. Думаю, на нем меня и сейчас никто не порвет. Хотя прошло уже лет 7 как мы в него не играем. Ну, да детство все это. Я уже и в современные то игры не играю. Не то что в дум.
Боюсь, даже предположить про каие лучи Вы начнете мне про Рэйл в КУ3 описывать , я не стараюсь под игру подвести научную базу, стрелеяю и стараюсь попасть, а сколько лучей, мне не важно.
В дум не играю, принципиально, не хочу портить воспоминания. Ку1 был велик, но это банальности.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Pavel Dvorkin, Вы писали: VD>>>Слушай, брось программировать. Береги нервы. PD>>Слушай, брось давать неумные советы. VD>По-моему, совет очень уместный. Ну, не должны программировать люди рассуждающие на уровне блоков памяти.
Влад. Только не надо говорить что все программирование ограничивается бизнес-приложениями. Блоки памяти тоже нужны, и так же важны. И даже программист бизнес-приложений который не знает что такое блоки памяти — негодный программист.
Здравствуйте, VladD2, Вы писали:
VD>>>Но есть другая простота. Это простота восприятия. Добиться ее можно грамотно подбирая и исползуя абстракции.
GN>>Мне кажется, он имел ввиду упрощение на самом верхнем уровне. В рамках целой задачи простой или сложный алго — лишь элементарное звено, упрощая его можно задачу и не упростить. В то же время — абстракция суть дополнительное элементарное звено, и слишком большое их количество может усложнить задачу.
VD>Прочитай внимательно выделенные слова.
Как я понял при первом прочтении, это означает в том числе и не злоупотребление ими?
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
Здравствуйте, GlebZ, Вы писали:
GZ>Влад. Только не надо говорить что все программирование ограничивается бизнес-приложениями.
Я где-то такое говорил?
GZ> Блоки памяти тоже нужны, и так же важны. И даже программист бизнес-приложений который не знает что такое блоки памяти — негодный программист.
Одно дело знать, что такое блок памяти, а другое думать только ими.
Поясню еще раз свою мысль. Pavel Dvorkin явно далеко не молодой пацан. Он учит людей в институте. Но в его рассуждениях я ни разу не слышал и намека на абстрацию. Вместо этого я вижу ужасающие примеры кода в стиле С времен его зарождения цель который всеми правдами и не правдами (чаще последним) доказать что думать нужно о "блоках памяти", а не о программе которая должна получиться в итоге.
Возможно я излишне резок, но меня просто выворачивает на изнанку когдя я представляю себе плоды подобного обучения.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, srggal, Вы писали:
VD>>Например, я не нелюблю незнакомое и не имею претензии к тому в чем не понимаю. Я критикую то что прекрасно понимаю и знаком с тем что, например, тебе не знакомо. От того собственно и кртикую. С++ протух и продолжает тухнуть с каждым годом. Выход нового стандарта затягивается. Да и надежды на реальные перемены в нем тоже таят на глазах. Вот на это я собственно и обращаю внимание.
S>Из Ваших постов, следует обратный вывод. Дискутировать не буду.
Это потому что ты имешь дурную привычку домысливать. Причем домысливать в худшую сторону (точнее в ту сторону куда удобнее).
Собственно наш ресурс довольно мощьная штука. Можешь поднять беседы 2001-2002 годов и поглядеть о чем я говорил в то время. Думаю, тебе не составит труда понять как зарождалось то мнение которого я придерживаюсь сейчас. Хотя на серьезное изучение у тебя уйдтет очень много времени . Ну, да если почитать только статьи, то тоже кое что можно понять.
В общем, вместо того чтобы домысливать лучше открой профайл оппонента и поройся в нем: http://rsdn.ru/Users/Profile.aspx
S>Боюсь, даже предположить про каие лучи Вы начнете мне про Рэйл в КУ3 описывать ,
Про рельсу особо много не скажешь. Хотя про то как из нее попадать в пылу борьбы поговорить можно. А вот про передвижение можно целый трактат написать. Не зная всего этого даже думать о мало мальски хорошем классе нельзя. Ну, да я в Ку3 далеко не мастер. Так что не мне обо всем это говорить.
S> я не стараюсь под игру подвести научную базу, стрелеяю и стараюсь попасть, а сколько лучей, мне не важно.
Это до тех пор пока тебя не поимели как катенка. А потом самолюбие берет свое и идешь читать на разные сайты. Причем оказывается, что самому дойти до всего этого почти не реально.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
IT>>Алгоритмы тут не причём. Упрощать нужно не их самих, а их реализацию.
VD>Опять неверный совет. Что значит упрощать реализацию? Более длинная и запутанная реализация может оказаться эффективнее в виду того, что запутанность — это оптимизации.
Влад, не путай упрощение и оптимизацию. Упрощению поддаётся любой код, даже сверх-оптимизированный.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, srggal, Вы писали:
VD>>>Например, я не нелюблю незнакомое и не имею претензии к тому в чем не понимаю. Я критикую то что прекрасно понимаю и знаком с тем что, например, тебе не знакомо. От того собственно и кртикую. С++ протух и продолжает тухнуть с каждым годом. Выход нового стандарта затягивается. Да и надежды на реальные перемены в нем тоже таят на глазах. Вот на это я собственно и обращаю внимание.
S>>Из Ваших постов, следует обратный вывод. Дискутировать не буду.
VD>Это потому что ты имешь дурную привычку домысливать. Причем домысливать в худшую сторону (точнее в ту сторону куда удобнее).
VD>Собственно наш ресурс довольно мощьная штука. Можешь поднять беседы 2001-2002 годов и поглядеть о чем я говорил в то время. Думаю, тебе не составит труда понять как зарождалось то мнение которого я придерживаюсь сейчас. Хотя на серьезное изучение у тебя уйдтет очень много времени . Ну, да если почитать только статьи, то тоже кое что можно понять.
VD>Вот, например, когда-то меня волновали вот такие вопросы: VD>http://rsdn.ru/article/?53
Не думали а об этом мнении, которое так похоже на ваши взгляды на безопастность ??
С врапперами вокруг хендлов не так все просто. Дело в том, что многие хендлы имеют ассоциированный с ними счетчик. Например, LoadLibrary-FreeLibrary, Create/OpenXX — CloseHandle. И если кто-то в этом случае будет вызывать исходные функции Win API напрямую, то без проблем не обойдется.
VD>Это до тех пор пока тебя не поимели как катенка. А потом самолюбие берет свое и идешь читать на разные сайты. Причем оказывается, что самому дойти до всего этого почти не реально.
Разорвали в клочья, но я не стал искать формул распространения луча рельсы в вакумме Я просто научился стрелять из нее в полете, в прожке, в развороте на 180 градусов, кроме того, научился допиливать пулеметом, снимать практически 100% со 100% вероятностью из шотгана...
И все равно меня сделали...
Я не комплексую по этому поводу — классные игроки, и я знаю игроков которые сделают тех, кто сделал меня....
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Sinclair, sorry, а не мог бы ты подсказать, как здесь эффективно сконкатенировать все же массив строк при том, что количество их определится в момент конкатенации? S>С массивом все вообще просто. См. string.Join.
Точнее string.Concat(). string.Join — это нечто большее чем просто конкатинация.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, WolfHound, Вы писали:
WH>ИМХО лучше так
Слишком много ошибок. WH>
WH>public static string Join(IEnumerable<string> strings)
// Имя явно не соотвествует поведению. Join соеденяет строки с использованием разделителя.
WH>{
WH> ICollection<string> collection = strings as ICollection<string>;
WH> if (collection != null)
WH> return Join(collection);
// Опять же нужно вызывать Concat.
WH> int n = 0;
WH> foreach(string s in strings)
WH> ++n;
WH> string[] arr = new string[n];
WH> n = 0;
WH> foreach(string s in strings)
WH> arr[n++] = s;
WH> return Join(arr);
WH>}
// Ну, а это вообще изврат полнейший. Проще и эффективнее просто использовать StringBuilder.
WH>public static string Join(ICollection<string> strings)
WH>{
WH> ICollection<string> collection = strings as ICollection<string>;
// Какой смысл проверять ICollection<string> на то что он является сам собой?
// Наверно имело смысл приводить к string[].
WH>public static string Join(string[] strings)
WH>{
WH> return string.Concat(strings);
WH>}
// Просто гениально. А что тогда не применять string.Concat напрямую?
WH>
WH>Таким образом мы избегаем двойного копирования строк.
Не факт, что просто StringBuilder окажется сильно медленее.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Это все верно, но тут ты играешь на том, что эти подстроки нужны и дальше (в данном случае будут использованы в rows). А вот когда они дальше как таковые не нужны (т.е нигде храниться не будут) — тут-то ты и проиграешь.
PD>p=strtok(myString,","); PD>while(p) PD>{ PD> printf("%d\n",p); PD> p = strtok(NULL,",") PD>}
PD>Здесь эти временные подстроки никому не нужны после печати. Если ты это перепишешь на С#, то получится
PD>int i, l=0; PD>while ((i=myString.IndexOf(",", l))!=-1) PD>{ PD> Console.WriteLine(myString.Substring(i, l-i); PD> l=i; PD>}
PD>В итоге для того, чтобы распечатать подстроки, ты создал их, напечатал, и, конечно, они стали добычей GC. А я их не создавал. Правда, строку испортил, но это уж так strtok сделана. Могу свою функцию написать, которая то же сделает, но строку портить не будет.
Блин, не могу смотреть на это торжество добра над разумом.
Ты хоть представляшь какова разница между скоростью создания объекта в GC-хипе и скоростью вывода информации на консоль? Это порядки!!! Тут временная строка вообще ничего не стоит!
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Да зачем же ? Пусть TestWord себе благополучно эту строку исследует (например, является ли слово палиндромом). Начало — p, конец — '\0', зачем мне тут подстроки в отдельный буфер копировать, когда и на месте все ясно ?
Знакток, блин... strtok модифицирует входную строку добавляя в нее нули вместо символов разделителей.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
Д>>я прекрасно понимаю, что я сделал со string Д>>длина каждой строки и должна вычисляться один-единственный раз, если тебя хоть сколько-то заботит производительность Д>>точнее — там, где она считывается из источника.
PD>А цикл, между прочим, выполняется 10000000 раз. Просто для того, чтобы время можно было замерить. А в реальной работе если он и выполнится 10000000 раз, то уж не с одними и теми же входными строками в любом случае Так что уж будь добр свой пример переделать таким образом, чтобы 10000000 он хотя бы имитировал, что строки у него новые.
а строки у тебя откуда берутся — святой дух присылает, что ли?
как я уже сказал, длина любой строки должна вычисляться один раз — когда она считывается из базы, или что там у тебя используется. После этого ее можно сохранить в ASCIIZ строку и потом перевычислять снова на каждый чих, или сохранить в std::string и больше никогда не вычислять. Доступно?
Здравствуйте, Дарней, Вы писали:
Д>Здравствуйте, Pavel Dvorkin, Вы писали:
Д>>>я прекрасно понимаю, что я сделал со string Д>>>длина каждой строки и должна вычисляться один-единственный раз, если тебя хоть сколько-то заботит производительность Д>>>точнее — там, где она считывается из источника.
PD>>А цикл, между прочим, выполняется 10000000 раз. Просто для того, чтобы время можно было замерить. А в реальной работе если он и выполнится 10000000 раз, то уж не с одними и теми же входными строками в любом случае Так что уж будь добр свой пример переделать таким образом, чтобы 10000000 он хотя бы имитировал, что строки у него новые.
Д>а строки у тебя откуда берутся — святой дух присылает, что ли?
Какая разница, откуда? Другая часть программы в буфер засылает.
Д>как я уже сказал, длина любой строки должна вычисляться один раз — когда она считывается из базы, или что там у тебя используется.
Да пойми же наконец, что не об этом речь. Кто же спорит, что длина одной строки должна вычисляться один раз! Но надо все же конкатенировать 10000000 раз не одну и ту же, а разные строки. Нет у меня такой зщадачи — одни и те же строки 10000000 раз конкатенировать!
Вот сделай так, чтобы у тебя строки были каждый раз разные. В реальной задаче кто-то будет в буфер новую строку засылать. В имитации можешь просто сделать вид, что строка каждый раз новая.
Это тест, не более. В этом тесте 10000000 конкатенируется 2 строки. Для теста можно не возиться специально, чтобы буферы ("1111...","222..2" ) были различны по содержанию — не все ли равно, что конкатенировать. Но нужно помнить, что содержимое буфера при каждом проходе цикла подразумевается различным. Поэтому я и внес присваивание szFirstName и szLastName под цикл — в этом имитация и заключается, строка якобы каждый раз другая. В реальной жизни szFirstName будет указателем на буфер, в котором при каждом вызове этой функции будет новое значение, а цикла не будет вообще — он здесь только для замера времени.
Можно, я слегка вмешаюсь — в основном в части, касающейся меня ?
GZ>А насчет учебы, так получилось что я самоучка. Меня никто не учил. Все познавал сам.
Я тоже.
GZ>Нет. Давай так. Павел привел действительно верные факты если брать алгоритмы программ. После этого — он перенес выводы на уровень архитектуры. Выводы в данном контексте становятся неверны.
Я не совсем понял, где я перенес выводы на уровень архитектуры. Я везде говорю о том, что не надо использовать неоптимальные решения на уровне реализации, а не архитектуры. Грубо говоря, не использовать два массива, где хватит одного. И я не совсем понимаю, почему хороший дизайн предусматривает плохую реализацию.
ИМХО здесь получается просто вот что. Делаем хороший дизайн, но при этом не думаем о том, как это реализоваться будет. Вот здесь объект такой-то создадим, такая-то функциональность. Здесь его копию сделаем, модифицируем эту копию — тоже понятно. И т.д. Все логично, все красиво — на уровне абстракций. Только 2 копии в итоге.
А, может быть, можно было одной обойтись, а изменения отдельно записать. И совсем не обязательно в ущерб дизайну и архитектуре. Просто при разработке архитектуры вспоминать иногда, что это стоит — на уровне блоков памяти
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Да пойми же наконец, что не об этом речь. Кто же спорит, что длина одной строки должна вычисляться один раз! Но надо все же конкатенировать 10000000 раз не одну и ту же, а разные строки. Нет у меня такой зщадачи — одни и те же строки 10000000 раз конкатенировать!
PD>Вот сделай так, чтобы у тебя строки были каждый раз разные. В реальной задаче кто-то будет в буфер новую строку засылать. В имитации можешь просто сделать вид, что строка каждый раз новая.
какая разница — одна и та же, или разные? Длина строки просто вычисляется где-то в другом месте (точнее — в коде, который читает данные из базы. но это уже детали)
Конкатенация ASCIIZ строк неэффективна в принципе, вот что я пытаюсь до тебя довести. Читал историю про маляра Шлемиэля?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Код, который читает данные из базы, длину не вычисляет. Нет такого в SQL SELECT, к примеру. Внутри себя этот SELECT на сервере я не знаю что делает, но мне на клиент в итоге строка попадает как последовательность ASCIIZ. Последовательность ASCIIZ — "сырые" данные, откуда они взялись — не важно. А в объекте string на входе конструктора эти же сырые данные (а как ты еще string сконструируешь, если не по ASCIIZ или по другому string ?), а вот в полученном объекте — уже с длиной. Т.е. длину при создании экземпляра string вычислили.
это как раз не "сырые" данные — ни один сервер БД не хранит данные в ASCIIZ
PD>Давай простой пример, искусственный, конечно. Есть огромный файл (1GB , в нем одна текстовая строка, в конце ее , конечно, 0D0A . Я открываю этот файл, делаю на него MMF, позиционируюсь в конец файла, заменяю 0D на 0, имею таким образом строку ASCIIZ. Обрати внимание — файл я не читал. Все — у меня char* pString готов.
а потом понадобилось добавить один символ к концу этой строки, и для этого тебе придется прочитать весь этот гигабайт в поисках маркера конца. Причем — перечитывать полностью каждый раз, как тебе понадобится добавить еще одну строку к его концу.
Хороший пример ты привел, ничего не скажешь.
PD>Да ведь во входном мире ничего другого нет. Есть некий входной массив байт (из файла, из сети, ...). Этот набор нам дают и все. И чем-то заканчивают, чтобы знали, когда остановиться. PD>gets банальный, например. А дальше уж наше дело — то ли string из него соорудить, длину мимоходом посчитав и время потратив, то ли не считать длину, отложить до того момента, когда понадобится (может, и не понадобится) . Кстати, в моем примере с конкатенацией я эту длину мог мимоходом вычислить.
не во входном мире, а в той библиотеке, которой ты пользуешься
>>Читал историю про маляра Шлемиэля?
PD>Нет.
...
PD>"Мне предложили вечную иглу для примуса, а я не купил. Мне не нужна вечная игла, я не собираюсь жить вечно"
PD>(C) Ильф и Петров, цитирую по памяти
Да, но это уже после того, как комбинатор стал миллионером.
Здравствуйте, Pavel Dvorkin, Вы писали:
GZ>>Нет. Давай так. Павел привел действительно верные факты если брать алгоритмы программ. После этого — он перенес выводы на уровень архитектуры. Выводы в данном контексте становятся неверны.
PD>И я не совсем понимаю, почему хороший дизайн предусматривает плохую реализацию.
Об этом уже писалось, по моему AndrewVK очень хорошо описал Мифы о рефакторинге
. Я бы туда запихнул Миф 9 — Рефакторинг увеличивает производительность кода. Строго наоборот. Он в подавляющем числе случаев уменьшает производительность кода.
Ну например, есть у нас такая фигня:
//оптимально по производительности
int cnt=GetCount();
....
for(int i=0;i<cnt;i++){...}
....
for(int j=0;j<cnt;j++){...}
//оптимально по дизайну
for(int i=0;i<GetCount();i++){....}
.......
for (int j=0;j<GetCount();j++){....}
Вполне понятно, что второй вариант и легче читается, и легко перенести второй цикл в другую процедуру. Но с другой стороны, оптимальный код по производительности выполняет GetCount только один раз. И нельзя предугадать что будет лучше. Ну например GetCount может быть просто свойством, а может быть достаточно сложной процедурой.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Я не совсем понял, где я перенес выводы на уровень архитектуры. Я везде говорю о том, что не надо использовать неоптимальные решения на уровне реализации, а не архитектуры. Грубо говоря, не использовать два массива, где хватит одного. И я не совсем понимаю, почему хороший дизайн предусматривает плохую реализацию.
Ага. У тебя выходит, что любая абстракция выхдящая за пределы POD (Plane Old Data) и массивы оных является злом, так как она не эффективно использует ресурсы.
str::string? Помилуйте, он же занимает память в хипе и вообще крайне не эффективен! CString, std::vector, std::map и другие бусты с лямбдами — это может отнять пару тактов процессора! О чем вы?!
В итоге ужасный непригодный к развитию и поддерживанию код смахивающий на С-код дремучих времен. Зато море слов о эффетивности, с примерами не делающими ровным счетом ничего.
PD>ИМХО здесь получается просто вот что. Делаем хороший дизайн, но при этом не думаем о том, как это реализоваться будет. Вот здесь объект такой-то создадим, такая-то функциональность. Здесь его копию сделаем, модифицируем эту копию — тоже понятно. И т.д. Все логично, все красиво — на уровне абстракций. Только 2 копии в итоге.
Ужас то какой? Особенно учитывая что копии управляются ЖЦ, а будующем возможно вообще будут устрняться компилятором или размещаться в стэке.
PD>А, может быть, можно было одной обойтись, а изменения отдельно записать. И совсем не обязательно в ущерб дизайну и архитектуре. Просто при разработке архитектуры вспоминать иногда, что это стоит — на уровне блоков памяти
Не. Ты о копиях только на словах говоришь. А на деле твой код выливается в возню с указателями и массивами размещенными в стэке.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Дарней, Вы писали:
Д>то есть, в данном случае размер хранится где-то отдельно. Иными словами, это не ASCIIZ строка
Да, конечно. Ты же заявил, что это файл придется просмотреть. чтобы в конец добавить, я и объяснил, как это делается. А так — конечно, не ASCIIZ. И длину считать придется, пройдя весь файл. И кстати, даже не знаю как — если запретить мне GetFileSize, то я и не представляю как ее определить самому.
А что, ты можешь предложить способ найти конец файла не зная его длину ?
Д>Забавно, что ты обратил внимание только на это. Д>Я даже не могу сказать, что ты не видишь леса из-за деревьев. Потому что ты настолько погрузился в разглядывание травы под своими ногами, что даже про существование деревьев забыл.
Наверное, пора прекращать дискуссию. Оставляю за тобой последнее слово (если хочешь ответить), я больше отвечать не буду. Как сказал один дипломат по поводу результатов переговоров :"Переговоры прошли блестяще — мы разошлись во мнении по всем без исключения вопросам"
Хм. Мне казалось. что я ответил. Оказывается, нет.
S>Здравствуйте, Pavel Dvorkin, Вы писали: PD>>Код, который читает данные из базы, длину не вычисляет. S>Еще как вычисляет. Неудачный пример.
Может быть.
PD>>Последовательность ASCIIZ — "сырые" данные, откуда они взялись — не важно. S>Нет уж позвольте. Мне вот очень интересно — откуда взялись эти сырые данные, и почему у них отобрали длину.
Я откуда знаю, почему ? Не возвращает fgets длину — и все. Могла бы, в принципе, но не возвращает. А на ней весь консольный ввод построен.
Да и в WinAPI то же. К примеру, edit. Естественно, у него можно и длину спросить, и строку. Есть, в общем, длина. Только от этого не легче — чтобы из этой ASCIIZ строки получить string, придется его конструктор вызывать, string(char*), а он эту строку к себе скопирует (и правильно, конечно, сделает) и длину пристроит.
А на fgets и edit вообще-то говоря, весь пользовательский ввод построен (ну не только, конечно). Прежде чем строка в БД оказалась, ее , скорее всего, кто-то вводил...
PD>>А в объекте string на входе конструктора эти же сырые данные (а как ты еще string сконструируешь, если не по ASCIIZ или по другому string ?) S>Как это? Миллион способов сконструировать строку есть.
Есть, не спорю. Только давай договоримся — из этого миллиона оставим только те, которые принимают на входе некий поток символов, а потом некий признак конца (не обязательно 0). Вот это и есть то, что я называю сырые данные.
PD>>Да ведь во входном мире ничего другого нет. Есть некий входной массив байт (из файла, из сети, ...). S>Неправда. Это какой-то не тот мир, который я знаю. Файлы уже лет тридцать как снабжаются длиной. Совершенно незачем выполнять последовательное сканирование для ее определения. Я понимаю, что трудно заставить в это поверить человека, привыкшего работать с магнитной лентой, но это так
Во-первых, на МЛ были файлы — по крайней мере, в СМ-4. И длина у них была. а во-вторых подобный ернический тон, пожалуйста, оставь.
PD>>Этот набор нам дают и все. И чем-то заканчивают, чтобы знали, когда остановиться. S>В 21 веке пора привыкать к тому, что строка в 99.9999% обладает длиной. И потерять эту длину можно только отрезав ее в одном месте. Чтобы тут же начать вычислять ее в другом.
Именно. Только от Win32 мы почему-то, как правило, получаем строки с отрезанной длиной. А потом ее пристраиваем — хоть в string, хоть в CString, хоть где-то еще.
Здравствуйте, Cyberax, Вы писали:
C>Ошибаетесь, вот МС показала здравый смысл — в Windows Vista все как и C>раньше будет основано на unmanaged-приложениях. В том числе и explorer с C>оффисом. И пока программисты, ратующие за увеличение производительности C>труда, будут писать чего-то там на WinForms или Avalon'е — МС будет C>совершенствовать свой набор оффисных программ, интегрированных через C>OLE2 (аналога которого в managed-мире нет и не предвидится).
Это банальная нехватка времени. Погоди несколько лет будет тебе и управляемый Офис, и все остальное.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>И да, и нет. Если переписать, то, может, оно и нормально будет — сейчас, без эксперимента, сложно наверняка говорить Но вот причина, почему они не выпускают Office, перекомпилировав его с помощью MC++ или C++/CLI, заключается как раз в заметно уменьшающейся производительности, которую показывают собранные таким образом приложения Office.
Это информация от группы Офиса, или умозаключения?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Но вот одно либо я недостаточно четко изложил, либо меня не поняли, либо не хотели понять. Я не призыаваю к тотальной оптимизации, это просто глупо, в конце концов. И те, кто меня в этом упрекают, зря стучатся в открытую дверь. Я выступаю за то, чтобы код на своем уровне писался эффективно. Чтобы не использовались явно избыточные по памяти или времени конструкции, когда это совсем не обязательно и вполне ясно, как без них обойтись, отнюдь не поступаясь при этом ясностью и четкостью.
Ага. Но по твоей версии использование класса вместо буфера в стеке — это лишнее выделение памяти. Использование паттерна — это лишний расход процессорного времени. И т.д., и т.п.
PD>И если интструмент спроектирован так, что он мне неизбыточное кодирование делать не дает, а заставляет или хотя бы толкает на это избыточное исходя из того, что нечего эти ресурсы экономить — вот с этим я и не согласен.
Вот-вот. Инструмент тебе предоставляет абстракцию — строка, а ты объявляешь ее избиточной.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2 wrote: > PD>KISS — Keep It Simple, Stupid! > > Помнится один авторитетный товаришь к этот прицип формулировал несколько > иначе "Все должно быть простым, настолько простым насколько это возможно > — но не проще.". И я с ним согласен.
Здравствуйте, Cyberax, Вы писали:
C>Следующий Оффис управляемым не будет, а что будет через 5 лет для меня C>пока не так важно — все успеет не раз поменяться.
Это и поменяется. Но думаю еще до этого сильно поменяется мнение о возможностях управляемого кода. Сейчас даже в Сан готовят революцию, а уж МС запрягла такое количество научных учереждений, что у меня сомнений не возникает.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Cyberax, Вы писали:
C>VladD2 wrote:
>> C>Следующий Оффис управляемым не будет, а что будет через 5 лет для меня >> C>пока не так важно — все успеет не раз поменяться. >> Это и поменяется.
C>С чего бы?
Увидишь. Как я уже говорил в научные исследования посвященные этой поблеме вкладываются огромные деньги. Но эти деньги просто не могут првратиться в реальные результаты сразу. На это нужно время. Первые ласточки уже есть. Те же дженерики в дотнете, например.
C>В бэтах Висты .NET играет роль пятого колеса, в Mac OS X (до C>которой Винде еще долго расти) управляемый код тоже далеко не главная часть.
C>Инфраструкту COM на .NET так нормально к Виста перенести и не смогли, а C>до следующей итерации пройдет немало времени.
Это не важно.
C>Вы не ловите момент: сейчас .NET и Java — это уже вчерашний день. C>Будущее за AJAX
Тебе виднее.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, gear nuke, Вы писали:
GN>ИМХО проблема не в языках. Многие алгоритмы имеют зависимости по данным (нельзя продолжать выполнение, пока не известен результат предыдущей операции). Да возьмём для примера любимый компилятор — даже если распараллелим компиляцию отдельных файлов, то как быть с линкером?
Хм. Распалаллелить парсинг и даже мемантический анализ можно. А линкер не везде есть. В дотнете, напрмер, он не нужен. JIT позволяет компилировать функции оп отдельности. Так что распараллелить этот процесс как два байта об асфальт.
Так что твои сомнения — это твои догмы.
Если хочешь посмотреть на то как будут параллелиться вычисления завтра посмотри на ФЯ. В них нет побочных эффектов при вычислениях, а это позволяет распараллеливать большинство вычислений. Причем автоматически.
GN>Можно вспомнить много таких "революционных" технологий даже на x86 — MMX, SSE, ... реальных выигрышей они не дают, если бы обычных регистров добавили, да нормальный (не стековый) FPU сделали — результат бы мог и лучше получиться. Но это бы была только *эволюция*.
Это заблуждение. В некоторых областях SSE дает огромный выигрыш. Просто фичи больно специализрованные. Хотя как не странно даже дотнет умеет их применять.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Да, бедные мы все. До появления Net писали себе char* и не знали. что не программы пишем, а только плодим "ни того, ни другого, да еще и дырка в безопасности впридачу"
Здравствуйте, VladD2, Вы писали:
VD>Распалаллелить парсинг и даже мемантический анализ можно.
Если совсем примитивно картину нарисовать — это будет работать, если исходник состоит из нескольких файлов. То есть, всё равно нужен какой-то (последовательный) механизм который будет выделять эти "параллельные" части. А вот как быть с той же таблицей символов? не пойму . Тут нужно, что бы язык на уровне синтаксиса не давал создавать такие проблемы. То есть, для старых языков не годится.
VD>А линкер не везде есть. В дотнете, напрмер, он не нужен. JIT позволяет компилировать функции оп отдельности. Так что распараллелить этот процесс как два байта об асфальт.
VD>Так что твои сомнения — это твои догмы.
Мои сомнения — не только мои догмы, но и догмы большого количества людей... Линкер-то и в С++ не особо нужен (ICC например идёт в этом направлении... и даже MSVC).
VD>Если хочешь посмотреть на то как будут параллелиться вычисления завтра посмотри на ФЯ. В них нет побочных эффектов при вычислениях, а это позволяет распараллеливать большинство вычислений. Причем автоматически.
А теперь представим, как все дружно пересаживаются на эти языки .
GN>>Можно вспомнить много таких "революционных" технологий даже на x86 — MMX, SSE, ... реальных выигрышей они не дают, если бы обычных регистров добавили, да нормальный (не стековый) FPU сделали — результат бы мог и лучше получиться. Но это бы была только *эволюция*.
VD>Это заблуждение. В некоторых областях SSE дает огромный выигрыш. Просто фичи больно специализрованные.
Я таких областей не знаю, можно подробнее? Если, например, говорить о параллельной обработке 4х float — так это маркетинг чистой воды. CPU и без того параллелит вычисления обычного последовательного кода. То есть, можно было довести до ума существующий механизм. SSE — по сути просто другой интерфейс к тем же самым вычислительным ресурсам. Где-то он удобнее и лучше, но это — результат того, что улучшали именно его, а не старый .
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
Здравствуйте, VladD2,
GN>>А когда начнут интегрировать RAM в корпус CPU (что бы избавиться от проблем с печатными платами), то как будем добавлять память?
VD>А надо? Для каждого периода времени есть некие негласные принятые объемы памяти. Ввести три градации: VD>1. Лоэнд — сейчас где-то 128 метров. VD>2. Лоэнд+ — 256 на сегодня. VD>3. Мидлэнд — 512. VD>4. Хайэнд — 1 Гиг. VD>5. Мечта идиота 4 Гб.
VD>Если это будет статическая память (попросу кэш), то ее можно тактировать частотой ядра и получать офигительные решения. Каждый класс к тому же будет иметь разное число ядер, разную тактовую частоу и т.п.
VD>На будющее просто выростут объемы памяти и частоты. Классы же останутся.
В этом месте возникает существенная проблема (не техническая, а финансовая). PC завоевал рынок именно благодаря тому, что множество компаний выпускают под него комплектуху. Если же у производителей CPU начнутся попытки подмять под себя рынок RAM — начнётся попросту война. Intel уже пытался играть на этом рынке (Rambus) и в результате его послали куда подальше.
Ну и всех революционеров этот рынок тоже не терпит. Itanium таму очень хороший пример (вспомните, что обещалось, когда он появился).
VD>Это кстати позволит делать девайсы миниатюрнее.
Думаю для определённых (узких) классов задач решения будут постепенно возникать. Я бы и сам с радостью купил писюк, который весь (кроме монитора) находится в клавиатуре .
VD>Можно пойти и таким путем. делать матери сразу под много процессоров с доставляемыми процессорными блоками. Каждый блок доставляет не только процессор но и память.
Сложность (и стоимость) таких матерей будет очень высокая. И опять же вернёмся к проблеме передачи данных по проводникам печатной платы.
ИМХО это всё перспективы ещё не завтрешнего дня.
P.S. особенно понравился пункт 5 .
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
Здравствуйте, Cyberax, Вы писали:
C>VladD2 wrote:
>> C>Это, наверное, если все сервисы сразу запустить. Я долгое время без >> C>проблем работал на P166+32Mb+NT SP6... >> ... в notpad-е...
C>Нет, на Java в Kawa + FAR. Ничего, все нормально было.
Не расказывай сказки. SP6 вышел уже после выхода других версий ОС и он резко поднимает требования к ресурсам. NT4 + SP6 по потреблению ресурсов от W2k ничем не отличается. А работать в 32 метрах было не фонтан и вообще без сервиспаков.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, gear nuke, Вы писали:
GN>Если совсем примитивно картину нарисовать — это будет работать, если исходник состоит из нескольких файлов. То есть, всё равно нужен какой-то (последовательный) механизм который будет выделять эти "параллельные" части.
Современные программы состоят из кучи (обычно сотни, а то и тысячи) едениц компиляции (читай файлов). В грамотно спроектированных языках такие еденицы содержат довльно независимые еденицы программы, например, классы. Распараллелить их парсинг не проблема. Прочто создаем такое количество экземпляров парсеров сколько есть физический ядер процессора и в перед...
Возможно с этим будут проблемы в С++, но меня в последнее время его проблемы больше не волнуют.
GN> А вот как быть с той же таблицей символов? не пойму .
На стадии парсинга у грамотно спроектированных языков нет нужды обращаться к таблице символов. Более того такие таблицы можно формировать параллельно для каждой еденицы компиляции, а потом банально объеденять.
После того как будет сформирована единая таблица символов ее можно банально сдублировать для всех параллельных процессов.
Кстати, как таковой таблицы сиволов в современных компиляторах нет. Там все куда сложнее. Но при грамотном проектировании все это пареллелится.
GN> Тут нужно, что бы язык на уровне синтаксиса не давал создавать такие проблемы. То есть, для старых языков не годится.
Это да. Но на то они и старые чтобы или мутировать, или отмерать.
GN>Мои сомнения — не только мои догмы, но и догмы большого количества людей... Линкер-то и в С++ не особо нужен (ICC например идёт в этом направлении... и даже MSVC).
Еще раз повторю. Проблемы С++ меня не колышат. Если они есть, то пусть это волнует Саттеров и Страуструпов. Пусть принимают решения. Или они держатся за традиции и хоронят этот язык, или они его меняют выбрасывая маразм и добавляя нужные расширения. Собственно Саттер вроде как уже меняет, но вот Страуструп явно противодействует. Боюсь он победит. Ну, да и фиг бы с ними.
GN>А теперь представим, как все дружно пересаживаются на эти языки .
А что мне предствлять то? Превью C# 3.0 видел? Там почти все изменения связанны с поддержкой функционального стиля. Так что процесс уже пошел. Сначала в языки общего назначения войдут функциональные конструкции и библиотеки спроектированные в функциональном стиле, а потом появятся средства автоматического распараллеливания. Естественно процесс будет куда сложнее, но я же говорю только о тендненциях.
GN>Я таких областей не знаю, можно подробнее?
Например, в Аква (графическом движке Мак ОС Х) при переносе Мак ОС на PC эти команды задействованы очень сильно. Потом все кодеки видио их исользуют. Игры... Даже при простых вычислениях компиляторы вставляют эти инструкции. Пока еще робко, но это уже связано с совместимостью. В дотнете, например, таких проблем нет, так что там они будут использоваться все чаще и чаще.
GN> Если, например, говорить о параллельной обработке 4х float — так это маркетинг чистой воды. CPU и без того параллелит вычисления обычного последовательного кода. То есть, можно было довести до ума существующий механизм. SSE — по сути просто другой интерфейс к тем же самым вычислительным ресурсам. Где-то он удобнее и лучше, но это — результат того, что улучшали именно его, а не старый .
SSE — это как бы специализированные подпрограммы реализованные на аппоратном уровне.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinclair, Вы писали:
S>Рекомендую попробовать проверить реальную зависимость быстродействия от checked/unchecked. Не стоит судить по количесту команд. repne scasd еще помнишь?
Скорость может упасть координально. Но дело не в этом. Если программа важная, но хрен с ней со скоростью. А если скорости и так зватает, то и думать не очем.
К тому же всегда можно услышав о проблеме неясного характера временно включить провекри переполнения. Если рпоблема в нем, то она будет быстро устранена.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, FR,
GN>>Думаю для определённых (узких) классов задач решения будут постепенно возникать. Я бы и сам с радостью купил писюк, который весь (кроме монитора) находится в клавиатуре .
FR>Давно забытое старое? (синклер, микроша, вектор, поиск)
Ну да . Дык если подумать — зачем нужен этот отдельный большой ящик...
FR>Да и сейчас есть тот же mac-mini
Mac может и хороший комп, но для себя не вижу никакого смысла в нём... разве что для понтов .
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
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, gear nuke, Вы писали:
GN>>Думаю для определённых (узких) классов задач решения будут постепенно возникать. Я бы и сам с радостью купил писюк, который весь (кроме монитора) находится в клавиатуре :)):up:.
FR>Давно забытое старое? :) (синклер, микроша, вектор, поиск) FR>Да и сейчас есть тот же mac-mini
Здравствуйте, VladD2, Вы писали:
VD>Возможно с этим будут проблемы в С++, но меня в последнее время его проблемы больше не волнуют.
А кого будут интересовать, что волнует Вас? Как показала жизнь, развитие индустрии идёт куда доллар покажет пальцем.
Кто сейчас делает наиболее качественные (с точки зрения производимого кода) компиляторы? Intel, MS и gnu.org. Первые 2 уже очень сильно обрадовались от появления Cell , а последние... у них даже препроцессор до сих пор отдельно от компилятора! .
VD>На стадии парсинга у грамотно спроектированных языков нет нужды обращаться к таблице символов. Более того такие таблицы можно формировать параллельно для каждой еденицы компиляции, а потом банально объеденять.
Действительно, от языка эта возможность больше всего зависит. Но выявление некоторых тупых ошибок, вроде 2х разный единиц трансляции с одинаковым содержимым будет уже только на стадии объединения происходить.
VD>После того как будет сформирована единая таблица символов ее можно банально сдублировать для всех параллельных процессов.
Скорее, даже не надо дублировать, доступ к ней на этом этапе достаточно read-only.
GN>>А теперь представим, как все дружно пересаживаются на эти языки .
VD>А что мне предствлять то?
А я о других людях говорю. Некоторых студентов на QuickBasic учат номера строчек писать .
VD>Например, в Аква (графическом движке Мак ОС Х) при переносе Мак ОС на PC эти команды задействованы очень сильно. Потом все кодеки видио их исользуют. Игры...
Использовать-то используют, но реального выигрыша не дают.
На примере AMD Athlon:
mulps ; (4 умножения) - 5 тактов, не параллелится
fmul; 4 такта, параллельно выполняется до 3х инструкций.
Это даже без учёта точности (у SSE хуже).
Единственно — для компилятора проще (с fpu единицы хорошо работают).
VD>SSE — это как бы специализированные подпрограммы реализованные на аппаратном уровне.
К таким "подпрограммам" можно отнести так же множество других команд. Например, call и ret .
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
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Я откуда знаю, почему ? Не возвращает fgets длину — и все. Могла бы, в принципе, но не возвращает. А на ней весь консольный ввод построен.
Гм. Боюсь тебя разочаровать, но никакого консольного ввода в окрестностях не наблюдается. Не пользуется им никто. ВинГУИ рулит. Увы. PD>Да и в WinAPI то же. К примеру, edit. Естественно, у него можно и длину спросить, и строку.
Именно! Более того, нельзя у него строку без длины получить:
int GetWindowText(
HWND hWnd,
LPTSTR lpString,
int nMaxCount
);
Return Values
The length, in characters, of the copied string, not including the terminating null character
PD>Есть, в общем, длина. Только от этого не легче — чтобы из этой ASCIIZ строки получить string, придется его конструктор вызывать, string(char*), а он эту строку к себе скопирует (и правильно, конечно, сделает) и длину пристроит.
Ну, здесь я ниче не понимаю. Я вижу, что из едита строка приезжает с длиной.
PD>Есть, не спорю. Только давай договоримся — из этого миллиона оставим только те, которые принимают на входе некий поток символов, а потом некий признак конца (не обязательно 0). Вот это и есть то, что я называю сырые данные.
Это ты здорово придумал. Если игнорировать окружающую действительность, то можно что угодно доказать. Давай договоримся лучше оставить те способы, которые применяются на практике.
PD>Во-первых, на МЛ были файлы — по крайней мере, в СМ-4. И длина у них была. а во-вторых подобный ернический тон, пожалуйста, оставь.
Как скажешь.
PD>Именно. Только от Win32 мы почему-то, как правило, получаем строки с отрезанной длиной.
Не мог бы ты показать мне те места в вин32, где мы получаем строку без длины? А то я может чего-то очень часто используемого не знаю.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, VladD2, Вы писали: VD>Скорость может упасть координально.
Может. Но у меня есть глубокое подозрение, что современный процессор практически не заметит лишней инструкции, потому как:
1. Ему надо проверять только флаг, а не память. Ближе, чем этот флаг, для процессора ничего нету.
2. Переполнения достаточно редки; а это означает редкость сброса конвеера из-за ошибки предсказания.
Таким образом, даже выполнение проверки в цикле будет скорее всего тратить меньше времени, чем выборка следующего аргумента из памяти. Конечно, надо тестировать. Но хороший тест написать — это время надо, а у меня его мало VD> Но дело не в этом. Если программа важная, но хрен с ней со скоростью. А если скорости и так зватает, то и думать не очем.
С этим я тоже согласен. Особенно я готов сказать "хрен с ним" потере в 2%. VD>К тому же всегда можно услышав о проблеме неясного характера временно включить провекри переполнения. Если рпоблема в нем, то она будет быстро устранена.
+.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
GZ>Только вопрос в том, что для кого программирование работа, а для кого-то призвание. И первых значительно больше чем вторых. GZ>Так что если говорить о промышленных языках, то я бы сказал что они есть компромисс — помочь первым, и не мешать вторым.
Абсолютно с Вами согласен. Кому ж ещё рутиной заниматься, кроме первых.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
S>Гм. Боюсь тебя разочаровать, но никакого консольного ввода в окрестностях не наблюдается. Не пользуется им никто. ВинГУИ рулит.
Боюсь тебя огорчить, но им пользуется нами всеми горячо любимый FAR. Это к примеру.
PD>>Да и в WinAPI то же. К примеру, edit. Естественно, у него можно и длину спросить, и строку. S>Именно! Более того, нельзя у него строку без длины получить: S>
S>int GetWindowText(
S> HWND hWnd,
S> LPTSTR lpString,
S> int nMaxCount
S>);
S>Return Values
S>The length, in characters, of the copied string, not including the terminating null character
S>
PD>>Есть, в общем, длина. Только от этого не легче — чтобы из этой ASCIIZ строки получить string, придется его конструктор вызывать, string(char*), а он эту строку к себе скопирует (и правильно, конечно, сделает) и длину пристроит. S>Ну, здесь я ниче не понимаю. Я вижу, что из едита строка приезжает с длиной.
Все верно, кто же спорит. Но возвращают строку отдельно, а длину отдельно. Вот если бы эта функция string STL вернула, другой разговор был бы. А так — придется этот, между прочим, char* буфер, передать string констуктору, который эту длину перевычислит.
Так что возвращает edit длину или нет — с точки зрения конструирования string не имеет значения.
PD>>Есть, не спорю. Только давай договоримся — из этого миллиона оставим только те, которые принимают на входе некий поток символов, а потом некий признак конца (не обязательно 0). Вот это и есть то, что я называю сырые данные. S>Это ты здорово придумал. Если игнорировать окружающую действительность, то можно что угодно доказать. Давай договоримся лучше оставить те способы, которые применяются на практике.
А какие способы для ввода в ЭВМ текстовой информации вообще существуют ?
PD>>Именно. Только от Win32 мы почему-то, как правило, получаем строки с отрезанной длиной. S>Не мог бы ты показать мне те места в вин32, где мы получаем строку без длины? А то я может чего-то очень часто используемого не знаю.
Еще раз — вспомни, из-за чего весь сыр-бор разгорелся. Дарней мне привел пример, где, по его мнению, string быстрее. Я ему объяснил, что string еще сконструировать надо из сырых данных, а это char*. Если ты мне можешь показать место в вин32, где возвращают уже сконструированные объекты классов string (или другие) — признаю свою неправоту.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Все верно, кто же спорит. Но возвращают строку отдельно, а длину отдельно. Вот если бы эта функция string STL вернула, другой разговор был бы.
Не, давай не будем придуриваться. Отсутствие в винапи нормального аналога строки не оправдание. Тебе дают буфер+длину. Если ты выкидываешь информацию о длине и пересчитываешь ее заново, то винапи не виноват. PD>А так — придется этот, между прочим, char* буфер, передать string констуктору, который эту длину перевычислит.
Хреновый значит конструктор. PD>А какие способы для ввода в ЭВМ текстовой информации вообще существуют ?
Да много способов есть. Банальный тайпинг, сканирование, штрих-сканирование...
А в чем, собственно, смысл? Из клавиатуры, кстати, строки вообще не вылезают, если на то пошло. Скан коды от нее приходят, и более ничего. И преобразование последовательности скан кодов в осмысленную информацию — дело промежуточного слоя. Вот мы рассмотрели в качестве такого слоя виндовый Edit. Ой-ой-ой! Он, оказывается, хранит у себя длину строки, вот нехороший какой. Не занимается он отслеживанием нуля в конце своего буфера. Отчего и лимит на размер строки в нем присуствует.
Кто у нас там еще умеет скан-коды в строки преобразовывать? Ах да, консоль. Конечно, в наш просвещенный век большая часть информации попадает в компьютер исключительно через Фар. Который, кстати, совершенно не факт, что использует именно консольный ввод. Не видал исходников, так что не уверен.
PD>Еще раз — вспомни, из-за чего весь сыр-бор разгорелся. Дарней мне привел пример, где, по его мнению, string быстрее. Я ему объяснил, что string еще сконструировать надо из сырых данных, а это char*.
Вот-вот. А я тебе рассказываю, что char* — это убогость, которая оправдания почти не имеет. Ты намеренно игнорируешь остальные компоненты возвращаемых значений. Эдак ты и на string будешь плеваться, уверяя, что ты хотел CString, а его иначе как через char* из string не получишь. PD>Если ты мне можешь показать место в вин32, где возвращают уже сконструированные объекты классов string (или другие) — признаю свою неправоту.
Я тебе показал то место, откуда можно взять сразу готовый объект строки без пересчета длины. Покажи мне теперь то место в винапи, где есть только char*, а длины нету. Не бойся — оно есть
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Все верно, кто же спорит. Но возвращают строку отдельно, а длину отдельно. Вот если бы эта функция string STL вернула, другой разговор был бы. S>Не, давай не будем придуриваться. Отсутствие в винапи нормального аналога строки не оправдание. Тебе дают буфер+длину. Если ты выкидываешь информацию о длине и пересчитываешь ее заново, то винапи не виноват.
В WinAPI не нормального аналога строки нет. В WinAPI класса строки нет. Это С интерфейс в основе своей (об OLE я не говорю). Так что не придкривайся сам — ты все отлично понмаешь.
PD>>А так — придется этот, между прочим, char* буфер, передать string констуктору, который эту длину перевычислит. S>Хреновый значит конструктор.
А напиши получше. Сам. Который эту строку и длину примет.
S>А в чем, собственно, смысл? Из клавиатуры, кстати, строки вообще не вылезают, если на то пошло. Скан коды от нее приходят, и более ничего. И преобразование последовательности скан кодов в осмысленную информацию — дело промежуточного слоя. Вот мы рассмотрели в качестве такого слоя виндовый Edit. Ой-ой-ой! Он, оказывается, хранит у себя длину строки, вот нехороший какой. Не занимается он отслеживанием нуля в конце своего буфера. Отчего и лимит на размер строки в нем присуствует. S>Кто у нас там еще умеет скан-коды в строки преобразовывать? Ах да, консоль. Конечно, в наш просвещенный век большая часть информации попадает в компьютер исключительно через Фар. Который, кстати, совершенно не факт, что использует именно консольный ввод. Не видал исходников, так что не уверен.
Несерьезно, ей-богу. Когда ты умные вещи говоришь — тебя интересно слушать. Когда изо всех сил пытаешься доказать то, что не доказывается (и ты сам это понимаешь) и занимаешься софистикой — интереса обсуждать это нет никакого.
S>Вот-вот. А я тебе рассказываю, что char* — это убогость, которая оправдания почти не имеет. Ты намеренно игнорируешь остальные компоненты возвращаемых значений. Эдак ты и на string будешь плеваться, уверяя, что ты хотел CString, а его иначе как через char* из string не получишь.
Здравствуйте, alexeiz, Вы писали:
A>std::string имеет конструктор, принимающий два итератора. Передаёшь в него указатели на начало и конец строки и никакого перевычисления длины не происходит. А ещё есть конструктор, который передаётся указатель на начало и длина.
Только при этом не забудь. что строка не должна быть в стековой памяти и т.д.
Здравствуйте, Pavel Dvorkin, Вы писали:
A>>std::string имеет конструктор, принимающий два итератора. Передаёшь в него указатели на начало и конец строки и никакого перевычисления длины не происходит. А ещё есть конструктор, который передаётся указатель на начало и длина. PD>Только при этом не забудь. что строка не должна быть в стековой памяти и т.д.
Откуда ты это взял?
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Sinclair, Вы писали:
S>>Хреновый значит конструктор. PD>А напиши получше. Сам. Который эту строку и длину примет.
пойдет? Типичный RTFM. И это я плохо плюсы знаю. Уж много лет на них не пишу ничего.
Смотрим в RTFM дальше.
CStringT(
const YCHAR* pch,
int nLength
);
Куда еще посмотреть? Может, ты мне покажешь плюсовый класс строки, который не умеет конструироваться из буфера и длины?
PD>Несерьезно, ей-богу. Когда ты умные вещи говоришь — тебя интересно слушать. Когда изо всех сил пытаешься доказать то, что не доказывается (и ты сам это понимаешь) и занимаешься софистикой — интереса обсуждать это нет никакого.
То же самое к тебе. Я вот не понимаю, почему ты утверждаешь, что char* первичен. Это, имхо, одна из тех очевидных истин, которая оказывается неправдой.
Пока что мы топчемся на месте: ты приводишь откровенно неверные утверждения в качестве аргументов.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Pavel Dvorkin, Вы писали:
WH>Откуда ты это взял?
Сорри, виноват. я просто не о том подумал. Если инициализация идет по другой строке, то, конечно, никаких проблем не будет. Я-то подумал. что речь идет не об входном объекте строки, а о входном char* буфере.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, VladD2, Вы писали: VD>>Скорость может упасть координально. S>Может. Но у меня есть глубокое подозрение, что современный процессор практически не заметит лишней инструкции, потому как: S>1. Ему надо проверять только флаг, а не память. Ближе, чем этот флаг, для процессора ничего нету. S>2. Переполнения достаточно редки; а это означает редкость сброса конвеера из-за ошибки предсказания.
Обожаю теоретиков. Но куда проще проверить. Я уже проверял. Вывод однозначный — checked() засунутый в "узкое горлышко" приводит к очень серьезному падению ироизводительности.
Хорошим примером где checked() мог бы пригодиться является создание компоратора. В приципе функцию CompareTo() для целых числе можно писать как "x — y". Но при переполнении получается задница. Если бы checked() работал действительно быстро, то можно было бы писать как-то так:
Но это только в теории. На практике это приводит к офигительным торомозам. Хотя теоритически красивая оптимизация. Кстати, об оптимизациях.
S>Таким образом, даже выполнение проверки в цикле будет скорее всего тратить меньше времени, чем выборка следующего аргумента из памяти. Конечно, надо тестировать.
От именно!
S>Но хороший тест написать — это время надо, а у меня его мало
Да, уж. Строчишь сообщения аки полемет, а на пару строк кода времени нет. Ладно, мне проще тест накатать:
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
class Program
{
static void Main()
{
// если раскоментарить строку ниже, то результат координально изменяется
// чем это можно объяснить я не понимаю. :(
//Console.WriteLine("Environment.Version " + Environment.Version);unchecked
{
Trace.Assert(CheckedCompareTo(1, 2) < 0);
Trace.Assert(UncheckedCompareTo(1, 2) < 0);
Trace.Assert(CheckedCompareTo(2, 1) > 0);
Trace.Assert(UncheckedCompareTo(2, 1) > 0);
Trace.Assert(CheckedCompareTo(1, 1) == 0);
Trace.Assert(UncheckedCompareTo(1, 1) == 0);
Unchecked();
Checked();
Unchecked();
Checked();
Unchecked();
Checked();
Unchecked();
Checked();
}
}
const int Count = 10000000;
[MethodImpl(MethodImplOptions.NoInlining)]
static void Unchecked()
{
Stopwatch timer = new Stopwatch();
timer.Start();
for (int i = 1; i < Count; i++)
{
UncheckedCompareTo(Count / 2, i);
UncheckedCompareTo(i, Count / 2);
UncheckedCompareTo(i, i);
}
Console.WriteLine("Время UncheckedCompareTo() " + timer.Elapsed);
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Checked()
{
Stopwatch timer = new Stopwatch();
timer.Start();
for (int i = 1; i < Count; i++)
{
CheckedCompareTo(Count / 2, i);
CheckedCompareTo(i, Count / 2);
CheckedCompareTo(i, i);
}
Console.WriteLine("Время CheckedCompareTo() " + timer.Elapsed);
}
[MethodImpl(MethodImplOptions.NoInlining)]
static int CheckedCompareTo(int x, int y)
{
try
{
return checked(x - y);
}
catch (OverflowException)
{
if (x > y)
return 1;
if (x == y)
return 0;
return -1;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static int UncheckedCompareTo(int x, int y)
{
if (x > y)
return 1;
if (x == y)
return 0;
return -1;
}
}
Результат:
Время UncheckedCompareTo() 00:00:00.1652819
Время CheckedCompareTo() 00:00:00.2136092
Время UncheckedCompareTo() 00:00:00.1409324
Время CheckedCompareTo() 00:00:00.2139755
Время UncheckedCompareTo() 00:00:00.1367955
Время CheckedCompareTo() 00:00:00.2105921
Время UncheckedCompareTo() 00:00:00.1406726
Время CheckedCompareTo() 00:00:00.2126683
S>С этим я тоже согласен. Особенно я готов сказать "хрен с ним" потере в 2%.
К сожалению это может оказаться 50%, и в самом узком месте. Хотя конечно пожно как раз это узкое место и оптимизировать с помощью unchecked.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подумал еще раз и решил, что я не уделил достаточного внимания своей аргументации, и к сожалению, ввязался в софистический спор. Нет ничего сложнее, чем доказывать то, что тебе кажется вполне очевидным. Попробую начать сначала.
Итак, ты утверждаешь, что винапи использует понятие "строка с длиной". На том основании, что практически везде эту длину нельзя не получить. Допустим, что это так.
Наверное, интерфейс, использующий некоторый объект, использует его не только на выходе, но и на входе. Иными словами, коль скоро он возвращает строки с длиной, то должен бы и на входе такие строки принимать, не так ли ?
Но — не принимает. Нет практически функций винапи, которые принимали бы на входе что-то, отличное от TCHAR*. Исключения есть — та же TextOut, к примеру, да и то в нее длина не для этого передается, а для того, чтобы можно было не всю строку вывести.
Кстати, на уровне чуть пониже такие объекты действительно есть. Я имею в виду Nt/Zw функции. Вот они, действительно, и принимают, и возвращают UNICODE_STRING, в которой, действительно, есть длина, а строка не обязательно заканчивается нулем. Иногда это прорывается и в винапи, например, Lsa функции.
А теперь вернемся к выходу от винапи. Действительно, тампочти всегда можно получить длину. Может, она там и хранится, в том же эдите, может, нет, неважно. Но то, что ее можно получить — не означает, что она там есть как часть инкапсуляции. Просто получить можно. Я в своей программе тоже, если надо, могу получить . Конечно, такой подход не соответствует принципам ООП, но никто же и не утверждает, что винапи — ОО интерфейс (я не говорю об ОЛЕ).
Вот если бы функции винапи принимали и возвращали бы объект, в котором строка неразрывно связана со своей длиной ( иными словами, без длины вообще не существует) — тогда да. Принимали бы и возвращали CString, к примеру — я бы сразу признал твою правоту. Но не принимают и не возвращают. Почему ?
Кстати, о CString. Ты не задумывался — почему он внутри себя строку все же с нулем хранит ? Вроде бы ему для внутренних дел — совсем не надо. И для работы с ним — тоже, если он уже сконструирован. Паскалевский string великолепно без этого нуля обходится, и в Шарпе, я полагаю, его тоже нет. Почему же здесь есть ? Сам догадаешься или подсказать ?
Ты меня как-то спрашивал про функции винапи, которые не возвращают длину. Я не ответил — не было времени подумать. А функций таких — сколько угодно. StrCat, к примеру. Или, еще хуже, PathCombine и другие Path- функции. И т.д. Кстати, как ты думаешь, зачем StrCat в винапи существует ? В С++ она нам не очень-то и нужна, у нас своя strcat есть ? Догадался зачем ?
Ну а что касается того, что тебе char* не нравится — отвечу твоими же словами насчет списка и массива. Где нужен список, а где массив. Где лучше иметь строку с длиной, а где — без длины. Только вот одно "но" при этом имеется. Из строки char* сделать строку с длиной мне никаких проблем не составит, даже на чистом С. Так что можешь сразу считать, что строка с длиной у меня всегда потенциально есть, и если реально понадобится — всегда будет. А вот как для объекта "строка с длиной" в том же Шарпе от длины избавиться ? . Конечно, средствами Шарпа имитировать строку с нулем несложно, только вот интерфейс для этого типа, боюсь, придется писать самому.
А зачем, собственно, я это рассказываю ? Сам ты это не знаешь, что ли ? Знаешь , конечно. А для чего тогда споришь ?
На этом, как говорили в старину, позвольте откланяться и прекратить свое участие в этой порядком мне надоевшей дискуссии. Оставляю за тобой последнее слово, если, конечно, захочешь ответить.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А все туда же. Взять эту CStringT и исходники посмотреть
PD> GetData()->nDataLength = nLength; PD> m_pszData[nLength] = 0; }
Прекрасно. У нас в руках улика! Браво, Холмс. PD>Так что имеем здесь нормальное копирование входной строки. Длина, правда, берется не из нее, поскольку в документации сказано, что
Именно, Холмс! Длина берется не из нее! Не вы ли только что уверяли, что нам придется повторно вычислять длину?
PD>Просто еще один конструктор у класса есть, вот и все.
Именно! Что и требовалось доказать. PD>Можно и другие придумать, если угодно. От этого ничего не меняется.
Как это не меняется? От этого утверждение
А вот чтобы из входного мира строки с длиной подавали — как правило, так не делают. А если даже и сделают, это тебе не поможет в случае со string — все равно констуктор string будет исходную строку просматривать и ноль искать. По крайней мере пока это string из STL
перестает быть правильным. И конструктор ноль не ищет, и строку нам с длиной подают. Итак, что мы имеем? Что нет оправдания супероптимальным небезопасным алгоритмам с копированием строк in-place. PD>И строка там опять-таки хранится с завершающим нулем.
Это как раз для тех, кто любит выкидывать длину и снова ее искать
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
второй проход получается, если:
— мы вызываем ToString несколько раз
— мы вызываем ToString не из того потока, в котором создавали стрингбилдер
— под стрингбилдер было выделено больше длины, чем фактически потребовалось.
В рассматриваемом случае ни одно из условий не выполняется.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Подумал еще раз и решил, что я не уделил достаточного внимания своей аргументации, и к сожалению, ввязался в софистический спор. Нет ничего сложнее, чем доказывать то, что тебе кажется вполне очевидным. Попробую начать сначала.
Совершенно верно. PD>Итак, ты утверждаешь, что винапи использует понятие "строка с длиной".
Нет. Я этого НЕ утверждаю.
Я опровергаю совершенно другое утверждение: "из окружающего мира к нам приходит строка без длины". Именно это утверждение ты использовал для того, чтобы оспорить результаты эксперимента, в котором безопасные операции над "строками с длиной" рвали предложенные тобой операции над строкой без длины. Напомню, что все это происходит в контексте фундаментального спора об оправданности небезопасного кода для повышения эффективности.
Итак, что мы имеем? На практике мы имеем полную возможность писать не только более безопасный код, но и более эффективный, построенный на строках с заранее вычисленной длиной.
Дальнейшие рассуждения про функции, не принимающие длину, я пропускаю, как нерелевантные. Мне не надо доказывать существование в винапи какого-то класса строки с длиной. Мне достаточно показать, что основные источники строк позволяют получить эту длину без дополнительных затрат. Также не относящимися к делу я считаю все рассуждения о наличии нулевого окончания в классах строк с длиной. Они, очевидно, нужны для передачи в устаревший код, который не способен использовать уже доступную информацию о длине строки.
PD>А зачем, собственно, я это рассказываю ? Сам ты это не знаешь, что ли ? Знаешь , конечно. А для чего тогда споришь ?
Я пытаюсь опровергнуть заблуждения догматического характера. В данный момент — ровно одно: то, что окружающий нас мир полон "голых" ASCIIZ — строк.
Особенно опасны эти заблуждения тем, что они оправдывают применение небезопасных техник программирования.
Действительно, в ВинАПИ есть функции, которые не позволяют получить длину строки без доп. затрат (как правило, в таких случаях можно получить точную верхнюю границу длины строки — а это позволяет нам все еще писать безопасные, хотя и не столь эффективные, алгоритмы). Тем не менее, вполне возможно свести использование таких строк к минимуму. Вот как, к примеру, выглядит дотнетовский аналог функции PathCombine:
Вряд ли он менее эффективен, чем стандартный PathCombine. И его еще можно сделать более эффективным, если немножко переписать и совместить проверку на невалидные символы с копированием строк.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
VladD2 wrote:
> C>Нет, на Java в Kawa + FAR. Ничего, все нормально было. > Не расказывай сказки. SP6 вышел уже после выхода других версий ОС и он > резко поднимает требования к ресурсам. NT4 + SP6 по потреблению > ресурсов от W2k ничем не отличается. А работать в 32 метрах было не > фонтан и вообще без сервиспаков.
Значит не sp6, а sp4/sp5 — не помню точно. Прекрасно помню, как
постоянно перегружался из Win98 (я в ней играл) в WinNT(так как она
намного стабильнее работала). Разница в скорости между 98 и NT была
заметная, но вполне терпимая.
Хотел было прекоатить — так не получается.
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Итак, ты утверждаешь, что винапи использует понятие "строка с длиной". S>Нет. Я этого НЕ утверждаю.
>Отсутствие в винапи нормального аналога строки не оправдание. Тебе дают буфер+длину. Если ты выкидываешь информацию о длине и пересчитываешь ее заново, то винапи не виноват.
Твое ? Тогда смотри дальше.
S>Дальнейшие рассуждения про функции, не принимающие длину, я пропускаю, как нерелевантные.
И в чем их нерелевантность ? В том, что они опровергают твою точку зрения, что
>Тебе дают буфер+длину. Если ты выкидываешь информацию о длине и пересчитываешь ее заново, то винапи не виноват
Где здесь дают эту самую длину ? Ответь, пожалуйста.
Где длина строки в текстовом файле ? Где она там хранится ? Там нет и нуля, конечно — по известным тебе историческим причинам. Но ограничитель там есть. (0D0A).
Где она после того, как fgets вернула строку?
>Мне достаточно показать, что основные источники строк позволяют получить эту длину без дополнительных затрат.
Если мы будем делить источники на основные и неосновные, то спор уйдет в никуда. Ты приводишь случаи, когда ее дают. Я — когда нет. Для того, чтобы ты был прав — необходимо, чтобы давали всегда. В противном случае твое утверждение необоснованно. Теорема, для которй есть хоть один опровергающий пример, опровергнута.
>Также не относящимися к делу я считаю все рассуждения о наличии нулевого окончания в классах строк с длиной. Они, очевидно, нужны для передачи в устаревший код, который не способен использовать уже доступную информацию о длине строки.
Нет. Они нужны для передачи этих строк в качестве входных аргументов этих самых винапи функций. Я, кстати, об этом написал, но ты предпочел на эту часть моего письма не ответить, а просто выкинуть ее. Можешь все же ответить?Формулирую прямо
Если в винапи используются строки с длиной, почему почти ни одной функции винапи эта длина не передается ? Почему они принимают только char* (wchar*) и вычисляют эту длину у себя внутри сами ?
И как следствие из этого — еще один вопрос
Почему, если они так делают и это правильно — когда я это делаю, это неправильно ? Их выход — мой вход, мой выход — их вход.
S>Действительно, в ВинАПИ есть функции, которые не позволяют получить длину строки без доп. затрат (как правило, в таких случаях можно получить точную верхнюю границу длины строки — а это позволяет нам все еще писать безопасные, хотя и не столь эффективные, алгоритмы).
Хм, а ведь в том примере, с которого весь сыр-бор разгорелся (с sprintf) я же битый час доказывал, что у меня есть эта самая точная верхняя граница. Но это вызвало твою негативную реакцию. Получается, коль винапи функции могут эту границу дать или ты как-то иначе оценить можешь — им доверять можно, а если я их даю — так нельзя ? Почему ?
Тем не менее, вполне возможно свести использование таких строк к минимуму. Вот как, к примеру, выглядит дотнетовский аналог функции PathCombine:
<skipped>
S>Вряд ли он менее эффективен, чем стандартный PathCombine. И его еще можно сделать более эффективным, если немножко переписать и совместить проверку на невалидные символы с копированием строк.
Охотно допускаю, что он не менее эффективен. Но какое это к делу имеет отношение ? И винапи PathCombine можно переписать, добавив ей длины и сделав безопасной. Но этого нет. В винапи. А то, что это есть или может быть в C# — я и не спорю.
Здравствуйте, Cyberax, Вы писали:
C>Значит не sp6, а sp4/sp5 — не помню точно.
Скорее всего 3. SP4 уеж поднял требования к памяти и был сильно глючным.
C> Прекрасно помню, как C>постоянно перегружался из Win98 (я в ней играл) в WinNT(так как она C>намного стабильнее работала). Разница в скорости между 98 и NT была C>заметная, но вполне терпимая.
Та же фигня. Но во времена SP5-6 я уже сидел на W2k.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Sinclair, Вы писали:
PD>>Где здесь дают эту самую длину ? Ответь, пожалуйста. S>Я показывал. Павел, я уже начинаю уставать.
Я тоже.
>Я попросил тебя дать примеры того, откуда берутся строки без длины. Ты привел пример с едитом — неправда, он отдает длину. Ты утверждал, что даже если бы длина была, все равно ее пришлось бы вычислять — неправда, есть невычисляющие конструкторы. Теперь мы наконец переходим к той части аргументации, которая не является банально неверной.
Пропустим сие утверждение.
PD>>Где длина строки в текстовом файле ? Где она там хранится ? Там нет и нуля, конечно — по известным тебе историческим причинам. Но ограничитель там есть. (0D0A). S>Ну и что? Как это нам помешает получить длину? Достаточно сделать вот так: S>
S>Вуаля! У нас есть длина строки от fgets без вычисления.
Как интересно! А откуда у тебя 4000 взялось, если не секрет? Допустить, что длина строки может быть больше, чем 4000, нельзя ? А если я тебе специально файл из одной текстовой строки сгенерирую длиной в 10 Кбайт, тогда как ?
Но не это главное. Это все так, мелочи. Не мелочи другое — эта длина тут вычисляется внутри fgets. Потому как найти длину строки в текстовом файле (вообще не говоря о программных средствах) нельзя кроме как, встав в некое смещение в этом файле, просматривать символы (байты) один за другим в поисках 0D. Нет другого способа. И кто-то это делать будет. Хоть gets, хоть ReadConsole, хоть какой-то метод из .Net 9а реально, конечно, нативный метод).
А ты в своем примере просто сыграл нга том. что fgets внутри себя, вычислив эту длину, продвинула file pointer на нее. Не она сама, конечно.
Синклер, это же задача на структуры данных. Тут дело даже не в файле вообще. При такой структуре данных нет иного способа разделить элементы, кроме как тупо побайтно проходить в поисках терминатора ? Неужели это тебе надо объяснять ? Хоть какте средства здесь используй — нет.
S>Павел, именно этим и отличается академический подход к разработке программ от прикладного. С прикладной точки зрения совершенно несущественно существование источников, которые передают информацию с потерями. Важнее — возможность воспользоваться нормальными источниками. Напомню, что ты пока не дал ни одного примера источника, который бы не позволил получить информацию о длине строки, кроме консоли.
Насчет потери информации — ИМХо в данном случае чистая казуистика.
Насчет примера — я тебе только что пример с текстовыми файлами привел.
Могу и другие примеры привести, подумать надо. Навскидку — LoadString. Можешь посмотреть, как в MFC CString они ее определяют, тихий ужас, потрассируй. Идиотизм, кстати, чистейшей воды. Не знаю даже, что студентам на этот счет говорить — для WinAPI.
S>Что это означает? Что пока что полезность строк без длины сводится к программам, интенсивно работающим с консолью. Все остальные программы, получается, только выигрывают от наличия длины.
Синклер, не надо сто раз про консоль. Не аргумент это. я тебе уже и другие примеры привел.
S>Значительная часть функций винапи придумана около 20 лет назад. Конечно, далеко не все из них были продуманы. В некоторых из этих функций длина просто не очень-то и нужна — вполне можно построить достаточно эффективный алгоритм и без нее. По крайней мере, достаточно эффективный в большинстве случаев. Ну вот как в PathCombine. Длина им не нужна — я и так могу спорить, что они просто тупо копируют строки одна за другой в отведенный буфер, почти как strcat. При этом они проверяют, не наступили ли на ноль в конце этого буфера, в целях безопасности. В случае передачи буфера недостаточной длины мы узнаем об этом гораздо позже, чем в случае строк-с-длиной.
Вот с этим вполне согласен. То. что этот интерфейс был создан, когда про ООП и не говорили — верно. То, что можно интерфейс, где строки нулем не терминируются, придумать — верно (да и зачем придумывать, см. string из pascal и C#). Более того, на тему о том, что эффективнее (ну не могу я без этого тоже готов спорить. Но притягивать за уши длину там где ее нет — честное слово, не стоит. А с винапи ситуация такова -ее в общем-то нет, по крайней мере очень часто. И чем ьебя это задевает — не понимаю. Скажи просто — интерфейс старый, ИМХО дурацкий, мне не по вкусу, я считаю, что лучше, если бы строки всегда с длиной были — да я с тобой сразу соглашусь и твое мнение вполне приму (хотя лично и не разделяю его). А ты зачем-то взялся доказывать. что в этом старом дурацком интерфейсе прямо таки везде заложены идеи а ля 2000 год. Ни к чему это, ей-богу.
А файл все же остается
PD>>И как следствие из этого — еще один вопрос
PD>>Почему, если они так делают и это правильно — когда я это делаю, это неправильно ? S>Из неверной посылки следует все что угодно. Они так делают и это неправильно.
Вот с этим тоже соглашусь. С твоей точки зрения неправильно. ИМХО. С моей — иначе ? Имеет моя точка зрения право на существование ?
PD>>Хм, а ведь в том примере, с которого весь сыр-бор разгорелся (с sprintf) я же битый час доказывал, что у меня есть эта самая точная верхняя граница. S>Это какая? У тебя не было никакой верхней границы. У тебя была наивная вера в существование верхней границы. А когда я говорю про точную верную границу, я говорю вот про что:
S>Допустим, мы воспользовались функцией fgets:
S>
<skipped>
S>
S>Итак, здесь мы имеем точную верхнюю границу для суммы всех длин: она равна, очевидно, 168. Мы можем спокойно использовать для конкатенации буфер этого размера. Не потому, что где-то в БД (внешней по отношению к нашей программе!) есть размер поля, и не потому, что оператор поклялся не засыпать на пробеле, а потому, что выполняются некоторые инварианты. Функция fgets так удачно написана.
Ну ей богу, несерьезно. Если у тебя из fgets эта длина определена как не более 168 — можно. Если валидатор на форме мне проверил строки (а ему сказано более 100 не принимать) — у меня наивная вера.
PD>>Но это вызвало твою негативную реакцию. Получается, коль винапи функции могут эту границу дать или ты как-то иначе оценить можешь — им доверять можно, а если я их даю — так нельзя ? Почему ? S>Потому, что ты свое значение границы высасываешь из пальца, а винапи поддерживает с математической точностью.
Но ты опять кусок из моего постинга выкинул. Придется мне его вновь привести
Ну а что касается того, что тебе char* не нравится — отвечу твоими же словами насчет списка и массива. Где нужен список, а где массив. Где лучше иметь строку с длиной, а где — без длины. Только вот одно "но" при этом имеется. Из строки char* сделать строку с длиной мне никаких проблем не составит, даже на чистом С. Так что можешь сразу считать, что строка с длиной у меня всегда потенциально есть, и если реально понадобится — всегда будет. А вот как для объекта "строка с длиной" в том же Шарпе от длины избавиться ? . Конечно, средствами Шарпа имитировать строку с нулем несложно, только вот интерфейс для этого типа, боюсь, придется писать самому.
Прокомментируй все же это , пожалуйста.
Я понимаю, что тебе мои заботы об эффективности надоели. Но все же представь — десятки миллионов строк в ОП хранить надо. Средняя длина — 10 байт. На поле длины — 4 байта. Итого 40% уходит на накладные расходы. Так что придется сокращать размер текстовой выборки. а длины и не нужны, а если нужны — их что, получить сложно ? В любой момент strcpy к твоим услугам. Да, на это время уйдет, но пусть оптимизировать надо по памяти, а не по времени. Вот тут я эти 40% и отыграю.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Andy77, Вы писали: S>Может, я чего не так понял?
S>второй проход получается, если: S>- мы вызываем ToString несколько раз S>- мы вызываем ToString не из того потока, в котором создавали стрингбилдер S>- под стрингбилдер было выделено больше длины, чем фактически потребовалось.
S>В рассматриваемом случае ни одно из условий не выполняется.
Всё правильно, я протормозил, посыпаю голову пеплом
Здравствуйте, VladD2, Вы писали:
GN>> Если совсем примитивно картину нарисовать — это будет работать, если исходник состоит из нескольких файлов. То есть, всё равно нужен какой-то (последовательный) механизм который будет выделять эти "параллельные" части.
VD> Современные программы состоят из кучи (обычно сотни, а то и тысячи) едениц компиляции (читай файлов). В грамотно спроектированных языках такие еденицы содержат довльно независимые еденицы программы, например, классы. Распараллелить их парсинг не проблема. Прочто создаем такое количество экземпляров парсеров сколько есть физический ядер процессора и в перед...
VD> Возможно с этим будут проблемы в С++, но меня в последнее время его проблемы больше не волнуют.
Очевидно, в C++ с этим никаких проблем не будет, т.к. язык изначально предназначен для раздельной компиляции. Компилятор VC++ умеет компилировать несколько файлов параллельно (например, недокументированная опция командной строки /MP2). В VS.Net 2003 этот режим был ограничен вариантами, где был не нужен доступ к *.pdb (т.е. по большей части варианты теоретические), в VS.Net 2005 это ограничение снято. Также есть режим параллельных билдов для vcbuild и devenv. GCC умеет билдить распределенно по машинам. Для VC++ есть сторонние утилиты, делающие более-менее то же самое.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Как интересно! А откуда у тебя 4000 взялось, если не секрет?
Ниоткуда. Я мог бы усложнить пример и перевыделять буфер удвоением, получая амортизированную производительность порядка log(lineLength). В данном случае я закладываюсь на то, что строка не будет длиннее 4000. PD>Допустить, что длина строки может быть больше, чем 4000, нельзя ? А если я тебе специально файл из одной текстовой строки сгенерирую длиной в 10 Кбайт, тогда как ?
я всего лишь прочитаю первые 4000 символов, и смогу корректно определить эту ситуацию за О(1). PD>Но не это главное. Это все так, мелочи. Не мелочи другое — эта длина тут вычисляется внутри fgets.
Нет. Павел, fgets не вычисляет ничего. Да, она работает при помощи банального сканирования. PD>Потому как найти длину строки в текстовом файле (вообще не говоря о программных средствах) нельзя кроме как, встав в некое смещение в этом файле, просматривать символы (байты) один за другим в поисках 0D. Нет другого способа. И кто-то это делать будет. Хоть gets, хоть ReadConsole, хоть какой-то метод из .Net 9а реально, конечно, нативный метод).
Павел, какое это отношение имеет к теме дискуссии? Даже если бы fgets знала длину строки заранее, это никак бы не ускорило копирование в буфер. Ты тут недавно утверждал, что для получения длины строки, возвращенной fgets, нужны дополнительные расходы. Это — неправда!
PD>Синклер, это же задача на структуры данных. Тут дело даже не в файле вообще. При такой структуре данных нет иного способа разделить элементы, кроме как тупо побайтно проходить в поисках терминатора ? Неужели это тебе надо объяснять ? Хоть какте средства здесь используй — нет.
При чем здесь структура данных?
PD>Насчет потери информации — ИМХо в данном случае чистая казуистика. PD>Насчет примера — я тебе только что пример с текстовыми файлами привел.
Твой пример, увы, ничего не доказывает. Он доказывает только одно — человек с мышлением, испорченным C, не будет искать способ эффективного вычисления длины при получении данных. Он лучше воспользуется небезопасным способом, типа strcat, для которого длину вычислять не надо. PD>Могу и другие примеры привести, подумать надо. Навскидку — LoadString. Можешь посмотреть, как в MFC CString они ее определяют, тихий ужас, потрассируй. Идиотизм, кстати, чистейшей воды. Не знаю даже, что студентам на этот счет говорить — для WinAPI. PD>Синклер, не надо сто раз про консоль. Не аргумент это. я тебе уже и другие примеры привел.
Ок, пока что у нас один открытый пример — LoadString. Все остальные магическим способом оказались заблуждениями. Здорово, правда?
PD>Вот с этим вполне согласен. То. что этот интерфейс был создан, когда про ООП и не говорили — верно. То, что можно интерфейс, где строки нулем не терминируются, придумать — верно (да и зачем придумывать, см. string из pascal и C#). Более того, на тему о том, что эффективнее (ну не могу я без этого тоже готов спорить. Но притягивать за уши длину там где ее нет — честное слово, не стоит. А с винапи ситуация такова -ее в общем-то нет, по крайней мере очень часто. И чем ьебя это задевает — не понимаю. Скажи просто — интерфейс старый, ИМХО дурацкий, мне не по вкусу, я считаю, что лучше, если бы строки всегда с длиной были — да я с тобой сразу соглашусь и твое мнение вполне приму (хотя лично и не разделяю его). А ты зачем-то взялся доказывать. что в этом старом дурацком интерфейсе прямо таки везде заложены идеи а ля 2000 год. Ни к чему это, ей-богу.
PD>А файл все же остается
В смысле? Какой файл? PD>>>И как следствие из этого — еще один вопрос PD>Вот с этим тоже соглашусь. С твоей точки зрения неправильно. ИМХО. С моей — иначе ? Имеет моя точка зрения право на существование ?
PD>>>Хм, а ведь в том примере, с которого весь сыр-бор разгорелся (с sprintf) я же битый час доказывал, что у меня есть эта самая точная верхняя граница. S>>Это какая? У тебя не было никакой верхней границы. У тебя была наивная вера в существование верхней границы. А когда я говорю про точную верную границу, я говорю вот про что:
S>>Допустим, мы воспользовались функцией fgets:
S>>
PD><skipped>
S>>
S>>Итак, здесь мы имеем точную верхнюю границу для суммы всех длин: она равна, очевидно, 168. Мы можем спокойно использовать для конкатенации буфер этого размера. Не потому, что где-то в БД (внешней по отношению к нашей программе!) есть размер поля, и не потому, что оператор поклялся не засыпать на пробеле, а потому, что выполняются некоторые инварианты. Функция fgets так удачно написана.
PD>Ну ей богу, несерьезно. Если у тебя из fgets эта длина определена как не более 168 — можно. Если валидатор на форме мне проверил строки (а ему сказано более 100 не принимать) — у меня наивная вера.
Ключевое слово — инкапсуляция. Здесь информация хранится и используется в одном и том же месте. А у тебя реализация одного участка программы катастрофическим образом зависит от другого участка программы.
PD>
PD>Но ты опять кусок из моего постинга выкинул. Придется мне его вновь привести
PD>Ну а что касается того, что тебе char* не нравится — отвечу твоими же словами насчет списка и массива. Где нужен список, а где массив. Где лучше иметь строку с длиной, а где — без длины. Только вот одно "но" при этом имеется. Из строки char* сделать строку с длиной мне никаких проблем не составит, даже на чистом С. Так что можешь сразу считать, что строка с длиной у меня всегда потенциально есть, и если реально понадобится — всегда будет. А вот как для объекта "строка с длиной" в том же Шарпе от длины избавиться ? . Конечно, средствами Шарпа имитировать строку с нулем несложно, только вот интерфейс для этого типа, боюсь, придется писать самому.
PD>Прокомментируй все же это , пожалуйста.
А что тут комментировать? Добавить длину к ASCIIZ стоит O(N). Убрать длину — O(0). Кто там заботился об эффективности? PD>Я понимаю, что тебе мои заботы об эффективности надоели. Но все же представь — десятки миллионов строк в ОП хранить надо. Средняя длина — 10 байт. На поле длины — 4 байта. Итого 40% уходит на накладные расходы. Так что придется сокращать размер текстовой выборки. а длины и не нужны, а если нужны — их что, получить сложно ? В любой момент strcpy к твоим услугам. Да, на это время уйдет, но пусть оптимизировать надо по памяти, а не по времени. Вот тут я эти 40% и отыграю.
При средней длине в 10 байт можно свести длину к байту, и получить 10%. Оп-ля, мы только что сэкономили 30%, не снизив безопасность.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, Коваленко Дмитрий, Вы писали:
Не, реальные пацаны пишут
КД>>for(int i=0, cnt=GetCount();i<cnt;++i){....}
КД>> GZ>Ну и че? Ну добавили суррогат. Усложнили читабельность кода.
Не, это называется "устранение преждевременной пессимизации" относительного того, что число элементов якобы может поменяться во время работы цикла. А компилятор, это такое существо, "полаганием" на которое лучше не злоупотреблять
GZ>Первое правило рефакторинга. Делай все как можно проще, и сложность сама придет.
Сдается мне, у нас разные представления о сложности
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Очевидно, в C++ с этим никаких проблем не будет, т.к. язык изначально предназначен для раздельной компиляции. Компилятор VC++ умеет компилировать несколько файлов параллельно (например, недокументированная опция командной строки /MP2). В VS.Net 2003 этот режим был ограничен вариантами, где был не нужен доступ к *.pdb (т.е. по большей части варианты теоретические), в VS.Net 2005 это ограничение снято. Также есть режим параллельных билдов для vcbuild и devenv. GCC умеет билдить распределенно по машинам. Для VC++ есть сторонние утилиты, делающие более-менее то же самое.
Теоритически да. Но практически при компиляции очень много времени уходит на компиляцию прекомпилируемых заголовков. А они как я понимаю компилируются последовательно. Гинковка опять таки становится узким местом. Хотя конечно для С++ параллельная компиляция актуальна куда сильнее. Даже с ней скорость компиляции очень удручающая. У меня знакомый народ использует какую-то хрень для распределения компиляции на несколько машин в офисе. И то жалуются.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Cyberax, Вы писали:
C>Надо сказать, что API для Вордовской системы проверки правописания C>свободно доступны. У меня, например, они прикручены к Far'у.
Насколько мне известно. Доступно только старое АПИ. Можно ссылочку?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2 wrote:
> C>Надо сказать, что API для Вордовской системы проверки правописания > C>свободно доступны. У меня, например, они прикручены к Far'у. > Насколько мне известно. Доступно только старое АПИ. Можно ссылочку?
Здравствуйте, VladD2, Вы писали:
VD>У меня знакомый народ использует какую-то хрень для распределения компиляции на несколько машин в офисе. И то жалуются.
А что они такое пишут? Индусы что-ли?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, VladD2, Вы писали:
IT>>Индусы что-ли?
VD>У тебя уже на них фобия.
У меня на них миллиард фобий. Или сколько их там.
VD>Нет конечно. Но не нужно быть индусом чтобы на плюсах создать проект который будет компилироваться пол часа на одной машине.
Они не на Watcom случайно проект делают, который состоит из одних шаблонов? Тогда в лёгкую. А так надо очень постараться.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, VladD2, Вы писали:
VD>Это старый АПИ. Оно не будет работать на машинах с новым вордом. По крайней мере на моей машине где стоит Word 2003 оно не работает.
Влад может на счет АПИ ты и прав, но у меня Word 2003 SP2 и оно работает.
Здравствуйте, FR, Вы писали:
GN>>Думаю для определённых (узких) классов задач решения будут постепенно возникать. Я бы и сам с радостью купил писюк, который весь (кроме монитора) находится в клавиатуре .
FR>Давно забытое старое? (синклер, микроша, вектор, поиск) FR>Да и сейчас есть тот же mac-mini
Мне вот нравятся маленькие такие ноуты, с книжку размером, с dvd-rw приводом, экранчиком 10".
Однако стоят такие хреновинки 50-60т.р. ($1600-2000).
Вот за 300 баксов бы я такой себе хоть щщас взял
Что интересно, стандартные большие ноуты стоят в 2-3 раза дешевле маленьких.
Когда цены на миниатюрные решения станут адекватными для простых граждан?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Компилятор с Фортрана на 96 КБайтах работал, c PL/1 — даже на 64 Кбайтах (до сих PD>пор не знаю, почему — PL/1 сложнее Фортрана), линкеру тоже 96 Кбайт хватало,
Они были жутко оверлейные... Чем им было доступно больше памяти, тем они быстрее работали. Оптимизирующему компилялятору PL/1 памяти было нужно заметно больше, чем стандартному.
S>Совершенно верно! Но, к сожалению, это была бы совсем другая программа. S>И Павел не будет ее писать. Потому, что strlen — это медленная операция, а он-то как раз хотел сэкономить лишний проход по данным.
а кто мешает юзать snprintf()? Как раз для таких случаев предназначена, свои проверки можно не делать.
Здравствуйте, GlebZ, Вы писали:
>>> А string вообще кошмар, но зато жутко удобный. ПК>>Это к уровню языка отношения не имеет. GZ>В честь чего. В С++ два основных типа строк.(пишу именно основных, чтоб не наезжали) Строка и нестрока, то есть string и char[]. string объект ООП — char[] наследие С. Кто из них высокоуровневая конструкция, а кто тормозная?
быстродействие выделения/удаления std::string напрямую зависит от алокатора. Все остальные операции сравнимы по эффективности... Некоторые алгоритмы могут работать гораздо быстрее за счет агрессивного инлайнинга.
Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[].
Здравствуйте, vdimas, Вы писали:
V>быстродействие выделения/удаления std::string напрямую зависит от алокатора. Все остальные операции сравнимы по эффективности... Некоторые алгоритмы могут работать гораздо быстрее за счет агрессивного инлайнинга.
V>Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[].
Ну уступающего char[] в стеке?
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, vdimas, Вы писали:
V>>быстродействие выделения/удаления std::string напрямую зависит от алокатора. Все остальные операции сравнимы по эффективности... Некоторые алгоритмы могут работать гораздо быстрее за счет агрессивного инлайнинга.
V>>Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[]. GZ>Ну уступающего char[] в стеке?
Здравствуйте, vdimas, Вы писали:
V>>>Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[]. GZ>>Ну уступающего char[] в стеке?
V>именно
Гонишь. Давай поясню что такое char[]. В отличие от string — это не массив, а всего лишь набор объектов. И даже копирование строк можно делать несколькими способами — перекопируя память через memmove, strcpy, или вручную построенным циклом. То есть способов не нарушающих инкапсуляцию char[] до фигищи. И кое какие из них — менее эффективны а какие-то более эффективны. К тому же strcpy можно легко проинлайнить, и я сомневаюсь что кто-то его обгонит, даже теоретически.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, vdimas, Вы писали:
V>>>>Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[]. GZ>>>Ну уступающего char[] в стеке?
V>>именно GZ>Гонишь. Давай поясню что такое char[]. В отличие от string — это не массив, а всего лишь набор объектов. И даже копирование строк можно делать несколькими способами — перекопируя память через memmove, strcpy, или вручную построенным циклом. То есть способов не нарушающих инкапсуляцию char[] до фигищи. И кое какие из них — менее эффективны а какие-то более эффективны. К тому же strcpy можно легко проинлайнить, и я сомневаюсь что кто-то его обгонит, даже теоретически.
а разве ты только копируешь строки??? мне казалось, что ты их еще сравниваешь и в коллекции ложишь и т.д.
В общем, могу дать стековый аллокатор и не смущай народ
GlebZ wrote: > V>именно > Гонишь.
Пример из моей BTL (Bicycle Template Library ) — политика хранения,
использующая небольшой стековый буфер для оптимизации:
///////////////////////////////////////////////////////////////////////////////////////
////// Small-Storage-Optimization
///////////////////////////////////////////////////////////////////////////////////////namespace aux
{
//This union is used to ensure that SSO storage elements will be
properly aligned.
template<size_t small_storage_size, class StorageT> union sso_storage_data
{
typedef typename StorageT::value_type value_type;
typename boost::type_with_alignment<
(boost::alignment_of<StorageT>::value >
boost::alignment_of<value_type>::value)
? boost::alignment_of<StorageT>::value
: boost::alignment_of<value_type>::value
>::type a;
char storage_[sizeof(StorageT)];
char data_[small_storage_size*sizeof(value_type)];
};
struct dummy_type { int dummy_; };
};
template<size_t small_storage_size,class StorageT> class sso_storage :
private boost::noncopyable,
//Use EBO for allocator. Note: workaround for VC bug!private StorageT::allocator_type::template rebind<aux::dummy_type>::other
{
//There is no sense in zero-sized sso!
BOOST_STATIC_ASSERT(small_storage_size!=0);
typedef typename StorageT::allocator_type::template rebind<
aux::dummy_type>::other rebound_alloc;
//Type of this class, useful for generic codetypedef sso_storage<small_storage_size,StorageT> this_class;
//Type of the small storagetypedef aux::sso_storage_data<small_storage_size,StorageT> data_type;
//Magic size indicates we've reverted to the main storage.static const size_t magic_size=small_storage_size+1;
//small_storage_size is insanely large - magic_size overflows!
BOOST_STATIC_ASSERT((magic_size>small_storage_size));
//SSO might be used only for POD-like types due to exception-safety
issues. TODO: add support for nothrowing copyctors.
BOOST_MPL_ASSERT((bitwise_moveable<typename StorageT::value_type>));
public://protected:typedef StorageT delegate_storage;
typedef typename StorageT::move_traits move_traits;
typedef typename StorageT::value_type value_type;
typedef typename StorageT::size_type size_type;
typedef typename StorageT::allocator_type allocator_type;
typedef sso_const_iterator<this_class> const_iterator;
typedef sso_iterator<this_class> iterator;
//Storage constructionexplicit sso_storage(const allocator_type &_alloc=allocator_type()) :
rebound_alloc(_alloc), size_()
{
}
//Destructor:
~sso_storage()
{
reset();
}
//Data accessor methods:
value_type* begin_ptr()
{
if (size_==magic_size)
return get_storage().begin_ptr();
return reinterpret_cast<value_type*>(buffer_.data_);
}
const value_type* begin_ptr() const
{
return const_cast<this_class*>(this)->begin_ptr();
}
iterator begin()
{
if (size_==magic_size)
return iterator(get_storage().begin());
else
return iterator(begin_ptr(),true);
}
const_iterator begin() const
{
//Note we have to remove constantness from the delegate iterator.if (size_==magic_size)
return const_iterator((const_cast<StorageT&>(get_storage())).begin());
else
return const_iterator(begin_ptr(),true);
}
value_type* end_ptr()
{
if (size_==magic_size)
return get_storage().end_ptr();
return reinterpret_cast<value_type*>(buffer_.data_)+size_;
}
const value_type* end_ptr() const
{
return const_cast<this_class*>(this)->end_ptr();
}
iterator end()
{
if (size_==magic_size)
return iterator(get_storage().end());
else
return iterator(end_ptr(),true);
}
const_iterator end() const
{
//Note we have to remove constantness from the delegate iterator.if (size_==magic_size)
return const_iterator((const_cast<StorageT&>(get_storage())).end());
else
return const_iterator(end_ptr(),true);
}
//Size/capacity:
size_type size() const
{
if (size_==magic_size)
return get_storage().size();
return size_;
}
size_type max_size() const
{
size_type sz;
if (size_==magic_size)
sz=get_storage().max_size();
else
sz=StorageT(*this).max_size();
assert(sz>small_storage_size); //Sanity checkreturn sz;
}
size_type capacity() const
{
if (size_==magic_size)
return get_storage().capacity();
return small_storage_size;
}
bool empty() const
{
return size()==0;
}
void set_size(size_type _new_size)
{
assert(_new_size<=capacity());
if (size_==magic_size)
get_storage().set_size(_new_size);
else
size_=_new_size;
}
allocator_type get_allocator_inst() const
{
return allocator_type(*this);
//const_cast<allocator_type&>(allocator_type(*this));
}
void reserve(size_type _new_size)
{
if (_new_size<=capacity())
return;
if (_new_size>max_size())
throw ::std::length_error("This storage can't handle such allocations");
if (size_==magic_size) //SSO is inactive
get_storage().reserve(_new_size);
else
{
//SSO is active, need to disable it.
allocator_type alloc(get_allocator_inst());
StorageT tmp(alloc);
tmp.reserve(_new_size);
move_traits::move(begin_ptr(),end_ptr(),tmp.begin_ptr(),alloc);
tmp.set_size(size());
reset();
create_storage();
get_storage().move_from(tmp);
}
}
void copy_from(const this_class &_other)
{
reset();
if (_other.size_==magic_size) //Check if SSO is inactive.
{
create_storage();
get_storage().copy_from(_other.get_storage());
}
else
{
assert(_other.size()<=small_storage_size); //Data should fit into
small buffer.
allocator_type alloc(get_allocator_inst());
//No need to call reserve, because we can't hit reallocation.
move_traits::copy(_other.begin_ptr(),_other.end_ptr(),begin_ptr(),alloc);
set_size(_other.size());
}
}
void move_from(this_class &_other)
{
reset();
if (_other.size_==magic_size) //Check if SSO is inactive.
{
create_storage();
get_storage().move_from(_other.get_storage());
_other.reset();
}
else
{
assert(_other.size()<=small_storage_size); //Data should fit into
small buffer.
allocator_type alloc(get_allocator_inst());
//No need to call reserve, because we can't hit reallocation.
move_traits::move(_other.begin_ptr(),_other.end_ptr(),
begin_ptr(),alloc); //May NOT throw.
set_size(_other.size());
_other.reset();
}
}
bool vacuum()
{
if (size_==magic_size)
return get_storage().vacuum();
return false; //We can't vacuum static storage.
}
void mutating()
{
if (size_==magic_size)
get_storage().mutating();
}
void swap(this_class & _other)
{
//Check if SSO is inactive - in this case just delegate swap to the
underlaying storages.
if (size_==magic_size && _other.size_==magic_size)
get_storage().swap(_other.get_storage());
else
{
//SSO is active at least on one storage, have to use slower swap.if (size_==magic_size || empty()) //SSO is active on the other storage.
{
//Move our data to the temporary storage (if it's present).
StorageT tmp(get_allocator_inst());
if (!empty())
tmp.move_from(get_storage());
reset();
//Move data from _other to our small buffer
move_from(_other);
_other.create_storage();
_other.get_storage().move_from(tmp);
} else
_other.swap(*this); //This will hit previous branch on recursion.
}
}
void reset()
{
if (size_==magic_size)
destroy_storage();
else
{
for(value_type* f=begin_ptr();f!=end_ptr();f++)
f->~value_type();
size_=0;
}
}
public: //Make custom methods accessible to client.bool sso_active() const
{
return size_!=magic_size;
}
StorageT& get_underlying_storage()
{
assert(!sso_active());
return get_storage();
}
private:
void create_storage()
{
assert(size_==0); //Storage must be clean
allocator_type alloc(get_allocator_inst());
new(buffer_.storage_) StorageT(alloc);
size_=magic_size;
}
void destroy_storage()
{
get_storage().~StorageT();
size_=0;
}
StorageT& get_storage()
{
assert(size_==magic_size);
return reinterpret_cast<StorageT&>(buffer_.storage_);
}
const StorageT& get_storage() const
{
assert(size_==magic_size);
return reinterpret_cast<const StorageT&>(buffer_.storage_);
}
data_type buffer_;
size_type size_;
};
Поддерживается автоматическое переключение на другую политику хранения,
если размер буффера оказывается недостаточным. В следующей версии еще
добавится более эффективная поддержка для контейнеров, где не нужен
непрерывный блок памяти.
Размер статического хранилища задается параметром темплейта. При желании
можно использовать alloca и задавать размер динамически.
Здравствуйте, Cyberax, Вы писали:
C>McSeem2 wrote:
C>Кстати, у нас в постановке проекта так и звучало: "Переделать прототип C>приложения c C# на С++" Между строчками читалось: "Эта <пиииииии> C>программа на C# не может делать ни <пииииииииии>. Сделайте нам нормальную."
Может это, того, проектную команду надо было поменять, а не язык? Потому как 99% ПО можно писать на чем угодно — разница т-ко в скорости разработки.
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, Павел Кузнецов,
>>> Излишней является любая оптимизация, которая не направлена на изменение ситуации, при которой система не способна уложиться в определенные в проекте временные рамки на том оборудовании, для работы на котором она предназначена.
ПК>>Только та, которая стоит дополнительного времени при разработке.
GN>ИМХО любая оптимизация будет стоить дополнительного времени, если проектировать и делать "абы работало".
В точку!
Не стыдно попасть в дерьмо, стыдно в нём остаться!
Здравствуйте, fplab, Вы писали:
F>В качестве продолжения посмотрите, коллеги, вот эту статью одного ассемблерщика http://www.wasm.ru/article.php?article=onebyte. Не перевелись еще богатыри
Поставил 3. Скорее за ссылку на великолепный рассказ. Спасибо!
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Пишите свои программы эффективно, господа! По крайней мере настолько, насколько PD>>это возможно!
E>Имхо, пока за скорость разработки платят больше, чем за скорость работы заказанной программы, этот призыв останется "гласом вопиющего в пустыне".
Потому, что сейчас разработка — pure business, а ранее было все-таки чем-то другим.
И вирусы раньше были маленькими, хитрыми, и местами даже с юмором(вывести на печать после каждого глагола ", бл#,").
А сейчас тупо трояны, которые могут выполнять чисто утилитарные функции(получить пароли или личные данные, помочь в ддос атаке). И они все тупы до ужаса. Какой-нить авторан-скрипт на VB, и экзешник. Фу. Я уже лет 10 не видел вируса-произведения искусства. Куда уж говорить про коммерческие программы.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.