Re[26]: Конец нересурсов
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 22.11.11 13:32
Оценка: +2
Здравствуйте, gandjustas, Вы писали:

G>>>Это какие тесты ты имеешь ввиду? Те которые проверяют поведение при неверных входных данных? Ты утверждаешь что их должно быть 70%-80%, а на проверку нужных сценариев предлагаешь отводить 20%-30% усилий?

V>>При оперировании состояниями в небезопасном к исключению коде это еще оптимистично, бо негативных сценариев всегда больше позитивных. Я бы сформулировал так: на каждый позитивный сценарий есть целая куча негативных.
G>Не спорю. Но ты на вопрос ответь. Ты предлагаешь тестировать негативные сценарии, которые по сути не нужны пользователю. Зачем это делать?

Это не смешно. И даже очень глупо.© Тем более, для того, кто тут направо и налево раздаёт рецепты правильного программирования.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[25]: Более того
От: Banned by IT  
Дата: 22.11.11 14:48
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Вот вот. А между тем они работают в тч. сиплюсниками на самых разных конторах и можешь быть спокоен — я тут абсолютно ни при чём.

Не, из этих персонажей один сидит на жаббе, двое вовсе потерялись из программирования.

I>Собственно судя по отзывам людей с твоей конторы про с++ на лялихе ...

С моей конторы?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[16]: Конец нересурсов
От: Banned by IT  
Дата: 22.11.11 14:48
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>>>А если учесть, что на менеджед пишется примерно 99% всех проектов, то это да, большой прикол.

BBI>>Ага, но при этом 90% софта native. Вот ведь парадокс.
I>Кто тебе такое сказал ?
Реальность. Тупо пошарился по всем доступным компам.

BBI>>Это ж ведь только с твоей колокольни такой вид открывается.

I>Нативный софт начали писать еще в 80х и с каждым годом в общей массе его становится меньше и меньше.
А ты это откуда взял?
У меня к примеру весь новый софт которым можно пользоваться почему то исключительно native.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[17]: Конец нересурсов
От: Banned by IT  
Дата: 22.11.11 14:48
Оценка: :))
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Вон, как здесь уже договорились до того, что аллокатор=гуру, скоро до указателей дойдёте.

Этот момент нереально повеселил. Шарпист добровольно по сути признал меня гуру, цирк на конной тяге!!!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[33]: Конец нересурсов
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.11.11 16:03
Оценка:
Здравствуйте, vdimas, Вы писали:

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


S>>Случайно тела методов были в теле класса. Те методы однострочные, жалко было места для дублирования сигнатуры. Но раз я обнаружил разницу в размере бинарников, то очевидно что варианты не эквивалентны. Тем более, что класс во втором случае имеет поле, в котором хранит переданный в конструкторе char.


V>Ну и что, если объект временный на стеке, его класс инлайный, происходит инициализация значением времени компиляции — это одно и то же в итоге. В общем, надо посмотреть на код, тогда я мог бы не гадать на кофейной куче... Может у тебя подчиненные парсеры хранятся как мемберы более высокоуровневых. Тоды ой.

Да, мемберы. Я пока не могу рассчитывать на auto-typed variables, потому мне надо как-то декларировать типы результатов комбинаций, т.к. я не хочу записывать высокоуровневый парсер одним выражением. Но и записывать в типе переменной тип комбинации тоже как-то лениво. Кроме того, там очень нехилые символические имена получаются (если парсеры низкого уровня записывать template параметрами). Пришлось создать виртуальные обертки для высокоуровневых парсеров, в которых записан лишь тип результата разбора, но нет типов парсеров-компонент.
В итоге, получившиеся парсеры стали выпадать из времени-компиляции во время выполнения, что и привело к необходимости хранить мемберы для парсеров более высокого уровня. В конце-концов я пришел к тому что вся информация, необходимая парсерам, хранится у них в мемберах.

S>>комбинаций немало (http://www.w3.org/TR/CSS2/grammar.html#scanner, http://www.w3.org/TR/CSS2/grammar.html#grammar)


V>Большой вложенности цепочек не вижу, однако.

Что считать большой?
num        [0-9]+|[0-9]*"."[0-9]+

пусть [0-9]- тривиальный парсер, и "." — тоже. Квантифиакторы — повышают вложенность на уровень. Алтернативы (|) тоже. Ну и сиквенсинг само собой. Итого навскидку глубина num равна 5.
В свою очередь num используется вот в таких шнягах
...
G        g|\\0{0,4}(47|67)(\r\n|[ \t\r\n\f])?|\\g
...
{num}{D}{E}{G}        {return ANGLE;}

считать глубину вложенности ANGLE мне уже лениво.
ANGLE учавствует в term, term в expr, expr дальше, каждый уровень подымает вложенность единиц на 3-5. В итоге, когда доберемся до stylesheet, вложенность может измеряться десятками этажей. Большая? Ну не знаю. Смотря для чего. Для символических имен — запредельная.

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

А быстродейстиве не критично вообще. Скажем так, быстродействие разбора CSS — меньшее, что меня беспокоит среди быстродействия в текущем проекте. Сейчас оно более чем удовлетворительное. Больше беспокоит объем бинариев, именно по этому поводу я вспомнил о template-взрыве.

V>К сожалению, в дотнете не так шоколадно, из-за того, что если тип по некоторому сценарию нужен для как ref, то такую декомпозицию с его участием в других местах легковесной не назовешь, ибо он везде пойдет как ref, добавляя уровень косвенности. В общем случае для дотнета описанный сценарий крайне вреден.

Не понял.

S>>генерики они другие. На темплейтах можно делать то, что нельзя на генериках и наоборот.


V>Генерики только имеют одно преимущество, позволяют оперировать с заранее неизвестным типом в рантайм, создавая экземпляры через рефлексию. Это такой же плюс, как и любые другие сценарии вокруг рефлексии. Так же удобны ограничения в виде специального синтаксиса, но ограничения можно использовать и в С++ через ср-ва языка, и даже эти ограничения могут поразнообразнее, но синтаксис не заточен именно под ограничения. Во всех остальных случаях генерики неизмеримо беднее.

Последний раз создавал экземпляры генериков через рефлексию где-то в 2004-м.

S>>Например, был жестоко обломан тем что темлейт функции-мемберы не могут быть виртуальными


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

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

S>>Вот еще пример, рекурсивный полиморфизм невозможно юзать во времени выполнения в C++, но вполне работает в C#. Если что — я об Purely Functional Data Structures (Queues based on implicit recursive slowdown).


V>Не уверен, что это так, если речь не идет о брутфорсной рефлексии времени исполнения.

Нет, не рефлексия. Типы создавал JIT, на сколько я помню.
V>Приведи пример на C#.
Я его встречал где-то пару лет назад, сейчас не найду.
V>Потому как если наоборот, то в плане метаинформации времени компиляции, ситуация в С++ всяко получше.
Времени JIT компиляции в случае с C#.
V>Ну и есть такая фишка, как т.н. статические визиторы. Т.е. это аналогичный обычному визитору механизм, полностью заресолвленный в статике там, где в аналогичном месте в C# он был бы заресолвлен лишь в динамике через двойную диспетчеризацию.
Да, есть, я знаю эту фишку. Но на этой фишке в C++ не построить живую очередь, которая сможет изменять свой размер в рантайме, скажем до размера нескольких десятков тысяч элементов. А на C# она работает (конечно, скорость ее работы далека от System.Generic.Collections.Queue<T>).
Re[26]: Конец нересурсов
От: vdimas Россия  
Дата: 22.11.11 16:45
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

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


Искать по
"нейтральный по отношению к исключениям код"
"безопасный по отношению к исключениям код"
Даже гуглится страница: http://www.rsdn.ru/res/book/net/cs2008.xml
Автор(ы): Трей Нэш
Книга ведущего специалиста в области технологий .NET представляет собой интенсивный курс по новейшей версии языка C#, воплотившей в себе важные дополнения и предлагающей среду, в которой функциональное программирование может органично переплетаться с обычным стилем императивного программирования на C#. Подробно рассматриваются такие темы, как фундаментальные принципы объектно-ориентированного проектирования, основные структуры данных, обработка исключений, делегаты, анонимные функции, контракты и интерфейсы, события, обобщения и многопоточность, а также нововведения наподобие лямбда-выражений, расширяющих методов и языка LINQ. Книга изобилует множеством примеров, которые не только иллюстрируют концепции, но также демонстрируют способы правильной разработки и умеренного их применения в реальных условиях. Книга рассчитана на программистов разной квалификации, а также будет полезна студентам и преподавателям дисциплин, связанных с программированием и разработкой для.NET.

и там даже есть разделы про откаты.

Еще посмотри популярный "read copy update". Дополнительно к блокировке писателей в этой модели удобно применить lock-free парадигму для любых многопоточных обновлений любых объектов, представляющих из себя состояние (не везде сказан про этот неплохой сценарий, приведу почти рабочий псевдокод):
Resource target; // целевой ресурс для обновления, лежит где-то мембером или статиком.
...
Resource resCurrent = target; // запоминаем локально ссылку на текущий экземпляр
do {
  Resource res = resCurrent;  // промежуточная переменная для оптимизации сценария CompareExchange
  
  Resource resNew = MakeCopyOfSomeDeep(res); // здесь будет 1% всех исключений
  Update(resNew, data);       // обновляем локальную копию, здесь будет 99% всех исключений

  // атомарно обновляем ссылку на данные, если до этого все прошло успешно
} while((currentTarget = Interlocked.CompareExchange(ref target, resNew, res)) != res);



G>Не спорю. Но ты на вопрос ответь. Ты предлагаешь тестировать негативные сценарии, которые по сути не нужны пользователю. Зачем это делать?

G>Ага, но если в десктопе писать большую часть приложения в таком же stateless стиле, то получается не хуже чем в вебе.

Не выйдет, ты же не только с данными работаешь, а со всем окружением вокруг программы, от которого изолирован в вебе. Если в вебе в случае ошибки ты отправил ее текс клиенту и "вышел", то в десктопе некуда выходить. Практически в КАЖДОМ сценарии тебе надо максимально адекватно обыграть любую ошибку. Без состояний на клиенте не обойтись. Напр, для твоего веба состоянием клиентской программы распоряжается браузер, + частично куки (хотя и тут гонки), и если для веба "нормально" показать ошибку и потерять нафик все результаты, например сообщение, которое тщательно 15 мин писал в этот форум прямо в браузере, то в обычной десктопной программе такое не прощается.

А что я вижу порой и что имею ввиду? Такие лихие зацикливания в попытках "правильно" обработать ошибки в клиентских программах... В половине случаев в цикле начинают мне показывать сообщения об ошибке, избавиться от этого никак, только снять процесс. Помнится, первые версии решарпера это нам тоже демонстрировали во всей красе. Непервые ночные билды тоже. Это тебе дотнетная прога из первых рук. Или, например, программа работала нормально, но после первой же странной ошибки, стала показывать сообщения об ошибке на каждое действие. Я такого в нейтивных программах не помню оч. давно.

G>Стейт как всегда присутствует в двух местах: интерфейс и хранилище данных. Первый нормально изолируется с помощью паттернов mv*, второй с помощью грамотно проработанных интерфейсов.


Ес-но, только у тебя "хранилище данных" — это и есть состояние твоей десктопной программы. С миллионном флагов и просто значений. И если ты сумеешь организовать транзакционность, т.е. чтобы обновление, скажем сотни полей, прошли либо все успешно, либо никто не прошел, то всё будет ок. Прямо как буд-то работаешь с транзакционной БД. О чем и речь. Просто в С++, ввиду того, что иногда приходится вручную следить, кто кем владеет и когда, безопасная схема слежения за ресурсами может быть только транзакционной или никакой. Устойчивость прикладной логики в этом случае — приятный бонус.

G>Я десктоп практически не пишу, если пишу то это SL для веба или виндафона или же windows-сервисы. Везде подход оправдал себя. Вызывает иногда повышенный расход ресурсов, но зато никаких наведенных эффектов и приложения работают гораздо надежнее. А уже после разработки основного функционала нередко приходится заниматься оптимизацией, удается сократить время работы и затраты памяти на 20% просто конфигурированием ioc-контейнера и кешей.


Ну, если ты только клиента для БД пишешь, то у тебя тоже, большая часть сценариев сводится к staless, а транзакционность за тебя БД умеет.
Re[34]: Конец нересурсов
От: vdimas Россия  
Дата: 22.11.11 16:56
Оценка:
Здравствуйте, samius, Вы писали:

V>>Ну и что, если объект временный на стеке, его класс инлайный, происходит инициализация значением времени компиляции — это одно и то же в итоге. В общем, надо посмотреть на код, тогда я мог бы не гадать на кофейной куче... Может у тебя подчиненные парсеры хранятся как мемберы более высокоуровневых. Тоды ой.

S>Да, мемберы. Я пока не могу рассчитывать на auto-typed variables, потому мне надо как-то декларировать типы результатов комбинаций, т.к. я не хочу записывать высокоуровневый парсер одним выражением. Но и записывать в типе переменной тип комбинации тоже как-то лениво. Кроме того, там очень нехилые символические имена получаются (если парсеры низкого уровня записывать template параметрами). Пришлось создать виртуальные обертки для высокоуровневых парсеров, в которых записан лишь тип результата разбора, но нет типов парсеров-компонент.
S>В итоге, получившиеся парсеры стали выпадать из времени-компиляции во время выполнения, что и привело к необходимости хранить мемберы для парсеров более высокого уровня. В конце-концов я пришел к тому что вся информация, необходимая парсерам, хранится у них в мемберах.

Так... тут надо выбрать время и вникнуть. Диагноз я поставил правильно, но чтобы показать решение, надо видеть, из чего оно состоит. Нет у тебя той старой версии, которая будет 5MB в бинарнике?


S>ANGLE учавствует в term, term в expr, expr дальше, каждый уровень подымает вложенность единиц на 3-5. В итоге, когда доберемся до stylesheet, вложенность может измеряться десятками этажей. Большая? Ну не знаю. Смотря для чего. Для символических имен — запредельная.


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


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

S>А быстродейстиве не критично вообще. Скажем так, быстродействие разбора CSS — меньшее, что меня беспокоит среди быстродействия в текущем проекте. Сейчас оно более чем удовлетворительное. Больше беспокоит объем бинариев, именно по этому поводу я вспомнил о template-взрыве.

С твоим вариантом уже разобрались, наверно же интересно, как оно бы выглядело, если бы...


V>>К сожалению, в дотнете не так шоколадно, из-за того, что если тип по некоторому сценарию нужен для как ref, то такую декомпозицию с его участием в других местах легковесной не назовешь, ибо он везде пойдет как ref, добавляя уровень косвенности. В общем случае для дотнета описанный сценарий крайне вреден.

S>Не понял.

Много маленьких объектов и развесистые графы внутренностей целевых объектов из этих маленьких не есть хорошо для дотнета. Большая косвенность будет на примитивных операциях и ГЦ не любит.


S>>>Например, был жестоко обломан тем что темлейт функции-мемберы не могут быть виртуальными


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

S>Мультиметоды. Точнее — двойная диспетчеризация шаблонного метода.

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


S>>>Вот еще пример, рекурсивный полиморфизм невозможно юзать во времени выполнения в C++, но вполне работает в C#. Если что — я об Purely Functional Data Structures (Queues based on implicit recursive slowdown).



V>>Ну и есть такая фишка, как т.н. статические визиторы. Т.е. это аналогичный обычному визитору механизм, полностью заресолвленный в статике там, где в аналогичном месте в C# он был бы заресолвлен лишь в динамике через двойную диспетчеризацию.

S>Да, есть, я знаю эту фишку. Но на этой фишке в C++ не построить живую очередь, которая сможет изменять свой размер в рантайме, скажем до размера нескольких десятков тысяч элементов. А на C# она работает (конечно, скорость ее работы далека от System.Generic.Collections.Queue<T>).

Мне нечего ответить, пока я не вижу о чем речь. С очередями и конвейерами я вожусь чуть более чем в каждом проекте, поэтому не понимаю пока, в чем проблема.
Re[18]: Конец нересурсов
От: MxMsk Португалия  
Дата: 22.11.11 17:24
Оценка: :)))
Здравствуйте, Banned by IT, Вы писали:

ГВ>>Вон, как здесь уже договорились до того, что аллокатор=гуру, скоро до указателей дойдёте.

BBI>Этот момент нереально повеселил. Шарпист добровольно по сути признал меня гуру, цирк на конной тяге!!!
Господа Шарписты, я не понимаю, для чего вы тратите силы и время на спор с такими людьми. Стоит завязать, причем насовсем.
Re[19]: Конец нересурсов
От: FR  
Дата: 22.11.11 17:31
Оценка:
Здравствуйте, vdimas, Вы писали:

V>А че-то D совсем притих... Никто там его покупать не собирается, случайно?


Не слышал такого.
Радует хоть что в последнее время новых фич не добавляют
http://www.d-programming-language.org/changelog.html
в основном багфиксы и расширение поддерживаемых платформ.
Вообще по моему для небольших проектов он уже вполне годен.
Re[35]: Конец нересурсов
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.11.11 17:41
Оценка:
Здравствуйте, vdimas, Вы писали:

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


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


V>Так... тут надо выбрать время и вникнуть. Диагноз я поставил правильно, но чтобы показать решение, надо видеть, из чего оно состоит. Нет у тебя той старой версии, которая будет 5MB в бинарнике?

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

S>>ANGLE учавствует в term, term в expr, expr дальше, каждый уровень подымает вложенность единиц на 3-5. В итоге, когда доберемся до stylesheet, вложенность может измеряться десятками этажей. Большая? Ну не знаю. Смотря для чего. Для символических имен — запредельная.


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

Э не, мне же нужен реюз. Т.е. однажды сконструированный парсер используется многократно, см. тот же num. Я не могу получить его на стеке и не запомнить где-то. А что бы запомнить нужно либо объявить тип (без auto) либо обернуть абстракцией (но тогда запомненное невзоможно будет передать лишь template параметром, надо будет еще и ссылку на абстрккцию тянуть и хранить ее в мемберах).

V>С твоим вариантом уже разобрались, наверно же интересно, как оно бы выглядело, если бы...

Мне тоже

V>Много маленьких объектов и развесистые графы внутренностей целевых объектов из этих маленьких не есть хорошо для дотнета. Большая косвенность будет на примитивных операциях и ГЦ не любит.

Насколько развесистые графы? Вот что ГЦ не любит — это большие объекты. А маленькие пережует, дай время

S>>Мультиметоды. Точнее — двойная диспетчеризация шаблонного метода.


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

V>Ну так когда вспомнишь задачу, посмотрим на статический С++ визитор в ее рамках.
Не спасет меня статический визитор, т.к. структура данных динамическая (дерево разнотипных элементов, создаваемое в динамике). Дерево динамическое, задач для диспетчеризации много, но не хочется писать диспетчеризацию под множество задач. Так что приза не будет. Обошелся шаблоном с условной логикой на тайп-тесте, благо значительного расширения типов иерархии предвидится.

V>Мне нечего ответить, пока я не вижу о чем речь. С очередями и конвейерами я вожусь чуть более чем в каждом проекте, поэтому не понимаю пока, в чем проблема.

www.cs.cmu.edu/~rwh/theses/okasaki.pdf (8.4 Queues and Deques)
Re[19]: Конец нересурсов
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 22.11.11 17:42
Оценка:
Здравствуйте, MxMsk, Вы писали:

ГВ>>>Вон, как здесь уже договорились до того, что аллокатор=гуру, скоро до указателей дойдёте.

BBI>>Этот момент нереально повеселил. Шарпист добровольно по сути признал меня гуру, цирк на конной тяге!!!
MM>Господа Шарписты, я не понимаю, для чего вы тратите силы и время на спор с такими людьми. Стоит завязать, причем насовсем.

Дык, в интернете кто-то не прав
Автор: Геннадий Васильев
Дата: 14.11.11
!
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[34]: Конец нересурсов
От: vdimas Россия  
Дата: 22.11.11 17:50
Оценка: 12 (1) +1 :))
Здравствуйте, Геннадий Васильев, Вы писали:

G>>Если же в реальном коде нет таких проблем как в указанном тобой примере, то зачем ты вообще писал пример?


ГВ>По-видимому, я всё-таки невнятно это как-то обозначил: приведённый код принципиально однопоточный. Многопоточным он "становился" только из-за ошибки в управлении потоками.


Да это неважно. Оппонент старательно обходит утверждение, что ошибка на управляемой платформе "сглаживалась". Какая разница в подробностях, коль сие св-во платформы гарантируется алгоритмом GC? Ну и к тому же программисту под веб, как видно, предварительно надо объяснять, почему довольно большие куски программ порой пишут принципиально как однопоточные, где о лишней синхронизации не может быть и речи. А это уже за рамками обсуждения.
Re[35]: Конец нересурсов
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 22.11.11 19:03
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Да это неважно. Оппонент старательно обходит утверждение, что ошибка на управляемой платформе "сглаживалась". Какая разница в подробностях, коль сие св-во платформы гарантируется алгоритмом GC? Ну и к тому же программисту под веб, как видно, предварительно надо объяснять, почему довольно большие куски программ порой пишут принципиально как однопоточные, где о лишней синхронизации не может быть и речи. А это уже за рамками обсуждения.


Сурово. Но справедливо.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[36]: Конец нересурсов
От: vdimas Россия  
Дата: 22.11.11 20:20
Оценка:
Здравствуйте, samius, Вы писали:

V>>Так... тут надо выбрать время и вникнуть. Диагноз я поставил правильно, но чтобы показать решение, надо видеть, из чего оно состоит. Нет у тебя той старой версии, которая будет 5MB в бинарнике?

S>Я пошукаю. Та версия была еще во время прототипирования, под контролем версий ее нет. Но где-то обязательно должна быть. Надо будет повыкидывать оттуда не относящееся к вопросу, вобщем займет какое-товремя.

ок

S>Э не, мне же нужен реюз. Т.е. однажды сконструированный парсер используется многократно, см. тот же num. Я не могу получить его на стеке и не запомнить где-то.


У классических комбинаторных парсеров нет состояния по окончании их работы. Комбинаторный парсер — это суть алгоритм, инкапсулирующий конкретную ветку правил. Только в самих правилах и есть отличия экземпляров парсеров (т.е. типов в данной схеме). А вся механика по построению AST и прочее — абсолютно одинакова, и эту механику можно из парсеров вынести и подавать как контекст/параметр со своим АПИ. Итого, в парсере не будет состояния, кроме состояния стека вызовов подчиненных парсеров, пока идет разбор по его алгоритму. Поэтому создание экземпляра — 0 тактов, удаление тоже 0 тактов. Хранить необязательно.

S>Насколько развесистые графы? Вот что ГЦ не любит — это большие объекты. А маленькие пережует, дай время


Это если на них ссылок нет и они из 0-го поколения. А если у нас все объекты состоят из десятка мелких, те в свою очередь еще из нескольких, то это мертвый груз для GC. Лишняя косвенность, ну и лишняя память, ведь блок в куче имеет служебную информацию, плюс надо дополнительно вместо самого объекта еще хранить ссылку на него, что в x64 оч много байт занимает. Неэффективно в общем. В дотнете я из-за этого делал отдельно value-type объекты, описывающие состояние, отдельно к ним ref-type обертки... двойная работа, в общем.

S>Не спасет меня статический визитор, т.к. структура данных динамическая (дерево разнотипных элементов, создаваемое в динамике). Дерево динамическое, задач для диспетчеризации много, но не хочется писать диспетчеризацию под множество задач. Так что приза не будет. Обошелся шаблоном с условной логикой на тайп-тесте, благо значительного расширения типов иерархии предвидится.


Пусть так. На C++, в отличие от, можно реализовать паттерн визитора в библиотечном виде. Я имею ввиду классический, который без тайп-тестов. И да, ни методы визитора, ни посещаемых объектов не обязаны быть виртуальными. По крайней сия библиотечная реализация не требует. Цимус визитора в возможности расширения функциональности над семейством типов без изменения самого семейства, а остальные подробности несущественны.


V>>Мне нечего ответить, пока я не вижу о чем речь. С очередями и конвейерами я вожусь чуть более чем в каждом проекте, поэтому не понимаю пока, в чем проблема.

S>www.cs.cmu.edu/~rwh/theses/okasaki.pdf (8.4 Queues and Deques)

Предположим, что с основными структурами данных я знаком, и даже представляю, как они организуются в функциональной парадигме. У нас же был вполне конкретный вопрос по механике С++ и сравнении возможностей генериков из C#, для какого-то совсем конкретного момента реализации, который не был показан. ИМХО, реализаций любого абстрактного алгоритма может быть гораздо больше одной, поэтому почти всегда можно выкрутиться.
Re[10]: Конец нересурсов
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 22.11.11 20:54
Оценка:
Здравствуйте, vdimas, Вы писали:

AVK>>А ты смотрел? Навскидку — основные изменения в 4 рантайме?


V>Я изменения смотрю по замерам, с некоторых пор.


Ясно. Т.е. не смотрел.
... << RSDN@Home 1.2.0 alpha 5 rev. 1537 on Windows 7 6.1.7601.65536>>
AVK Blog
Re[37]: Конец нересурсов
От: samius Япония http://sams-tricks.blogspot.com
Дата: 22.11.11 22:56
Оценка:
Здравствуйте, vdimas, Вы писали:

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


S>>Э не, мне же нужен реюз. Т.е. однажды сконструированный парсер используется многократно, см. тот же num. Я не могу получить его на стеке и не запомнить где-то.


V>У классических комбинаторных парсеров нет состояния по окончании их работы. Комбинаторный парсер — это суть алгоритм, инкапсулирующий конкретную ветку правил. Только в самих правилах и есть отличия экземпляров парсеров (т.е. типов в данной схеме). А вся механика по построению AST и прочее — абсолютно одинакова, и эту механику можно из парсеров вынести и подавать как контекст/параметр со своим АПИ. Итого, в парсере не будет состояния, кроме состояния стека вызовов подчиненных парсеров, пока идет разбор по его алгоритму. Поэтому создание экземпляра — 0 тактов, удаление тоже 0 тактов. Хранить необязательно.

Это все мне известно. Но цепочка построения типов упирается в некоторые сложности. Допустим, мне нужно записать
(p1 | p2)+

Есть вариант строить типы:
typedef ... p1;
typedef ... p2;

typedef Many<
    a, // тип результата разбора
    OrElse<b, p1, p2> // b-тип парсера, который квантифицируем, p1 и p2 - типы парсеров
    1, // минимальное число вложений
    inf, // максимальное число вложений
    acc  // аккумуляторная функция аки в fold-е
    > MyParser;

Мне этот вариант ох как не нравится, потому как из короткой записи мы получаем очень длинную и практически нечитаемую. В непосредственном комбинировании типов мы не можем использовать перегруженные операторы.
Еще вариант, комбинировать выражения. Но по результату выражения мы не можем ввести тип результата (что бы его за-typedef-ить):
auto p1 = ...
auto p2 = ...

auto MyParser = Many<1, inf, acc>(p1 | p2);
// auto MyParser = OneOrMore<acc>(p1 | p2);

Так вот, проблема в том, что написать вместо auto, если Many возвращает результат типа ManyParser<1,inf,acc,Tp1,Tp2>, притом что p1 и p2 нетривиальные парсеры?
Мы рассмотрели тривиальное выражение (p1|p2)+, а нужны куда более серьезные...
(Писал навскидку, такого кода у меня нет)

Это только синтаксиеческая проблема подхода без состояний. Есть еще взрыв... Мне сложно прикинуть, сколько в грамматике CSS использован квантификатор. Допустим, 100 раз (явно меньше, чем есть на самом деле). Это значит, что метод разбора ManyParser::Parse будет размножен именно 100 раз.

Можно пойти путем вытаскивания необходимой информации из template параметров, например превратить RangeParser<'0','9'> в RangeParser, хранящий состояния '0' и '9'. Таким образом, парсеры, разбирающие диапазоны кодепоинтов, будут иметь один тип. Но мы внесли состояние, правда неизменяемое. Я пошел еще дальше и унифицировал все парсеры, результатом которых является значение определенного типа. Т.е. все парсеры, разбирающие отдельные символы, имеют один тип, парсеры, разбирающие строки (std::wstring) имеют другой тип и т.п.
Тогда мы существенно уменьшим количество типов, получающихся при комбинации парсеров. Т.е. сколько бы мы ни комбинировали парсеры, разбирающие отдельные символы, результатом (|) получим парсер, разбирающий символы и только. Т.е. удалось избежать комбинаторного взрыва типов парсеров за счет внесения состояния в парсеры. Естественно, состояние не изменяется в процессе разбора, но оно есть и его надо хранить в мемберах.

Кстати, система типов дотнета позволяет построить такой парсер практически без напряга. Не знаю, в какой объем разворачивается IL, но на диске его порядка 150Кб.

V>Это если на них ссылок нет и они из 0-го поколения. А если у нас все объекты состоят из десятка мелких, те в свою очередь еще из нескольких, то это мертвый груз для GC. Лишняя косвенность, ну и лишняя память, ведь блок в куче имеет служебную информацию, плюс надо дополнительно вместо самого объекта еще хранить ссылку на него, что в x64 оч много байт занимает. Неэффективно в общем. В дотнете я из-за этого делал отдельно value-type объекты, описывающие состояние, отдельно к ним ref-type обертки... двойная работа, в общем.

То есть это было причиной падения производительности (лишняя косвенность, напряги GC)?

S>>Не спасет меня статический визитор, т.к. структура данных динамическая (дерево разнотипных элементов, создаваемое в динамике). Дерево динамическое, задач для диспетчеризации много, но не хочется писать диспетчеризацию под множество задач. Так что приза не будет. Обошелся шаблоном с условной логикой на тайп-тесте, благо значительного расширения типов иерархии предвидится.


V>Пусть так. На C++, в отличие от, можно реализовать паттерн визитора в библиотечном виде. Я имею ввиду классический, который без тайп-тестов. И да, ни методы визитора, ни посещаемых объектов не обязаны быть виртуальными. По крайней сия библиотечная реализация не требует.

При отсутствии виртуальных методов и тайп-теста (либо его заменителей) мы не сможем работать с subtype-полиморфными данными. А именно это мне требовалось.

V>Цимус визитора в возможности расширения функциональности над семейством типов без изменения самого семейства, а остальные подробности несущественны.

Это известно.

S>>www.cs.cmu.edu/~rwh/theses/okasaki.pdf (8.4 Queues and Deques)


V>Предположим, что с основными структурами данных я знаком, и даже представляю, как они организуются в функциональной парадигме. У нас же был вполне конкретный вопрос по механике С++ и сравнении возможностей генериков из C#, для какого-то совсем конкретного момента реализации, который не был показан. ИМХО, реализаций любого абстрактного алгоритма может быть гораздо больше одной, поэтому почти всегда можно выкрутиться.

Естественно можем, но в случае с C++ придется ослабить типизацию, для того что бы работать с такой структурой в рантайме.
Re[17]: Конец нересурсов
От: ArtemGorikov Австралия жж
Дата: 22.11.11 23:26
Оценка:
Здравствуйте, vdimas, Вы писали:

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


I>>Расклад по тому, что нынче пишется в каких объемах можно сделать тупо по количеству вакансий. Как то я не вижу значительного кол.ва вакансий на с++ и не вижу, что бы ЗП в с++ отражали спрос на с++


V>Дык, я же говорю, дефицит. Как ни посмотришь требования к С++-программисту, от года, или типа таких:

V>

V>Требования к кандидату
V>• Понимание ООП проектирования и программирования
V>• Практический опыт разработки программ на С++ (MS Windows)
V>• Знания и практический опыт использование библиотек MFC, STL, Boost
V>• Практический опыт разработки многопоточных приложений (синхронизация, разделяемые данные, обмен сообщениями)
V>• Опыт командной работы

Это ищут студента на поддержку наследия 90-х?

V>Последние годы требования к плюсовикам настолько деградировали в объявлениях, что эти объявления можно читать как "ну придите же хоть кто-то". И предлагают там же ЗП, сопоставимую с разработчиками ASP.Net, для которых нехилый конкретный список требований, технологий, практик и т.д.

Это список с чем работал или читал,- он не отражает, какой сложности задача по силам.

V>Вижу так же, что по грамотным плюсистам работают исключительно headhunters у нас, сами дергают конкретных людей, исключительно переманивая с места на место. Лучше посмотреть на каком-нить http://nyjobsource.com/ , бо у нас 99% спецов-плюсистов тупо уехало и не вернулось. Когда я последний раз внимательно смотрел, то ЗП С++ разработчиков легко были 140-170к, аналогичных по опыту дотнетчиков 100-120к.

Это вообще феерический бред. За "Знания и практический опыт использование библиотек MFC, STL, Boost" и опыт от 3 лет в Сиднее, к примеру, ищут на 65к, в глубокой ж за Westmead автобусом 20 минут.
Ваки на C++ на 140-200 есть, но они подразумевают нехилые знания финансов и какой-то опыт юниксового C++ (упор на финансы).
Re[27]: Конец нересурсов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.11.11 07:00
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Еще посмотри популярный "read copy update". Дополнительно к блокировке писателей в этой модели удобно применить lock-free парадигму для любых многопоточных обновлений любых объектов, представляющих из себя состояние (не везде сказан про этот неплохой сценарий, приведу почти рабочий псевдокод):

V>
V>Resource target; // целевой ресурс для обновления, лежит где-то мембером или статиком.
V>...
V>Resource resCurrent = target; // запоминаем локально ссылку на текущий экземпляр
V>do {
V>  Resource res = resCurrent;  // промежуточная переменная для оптимизации сценария CompareExchange
  
V>  Resource resNew = MakeCopyOfSomeDeep(res); // здесь будет 1% всех исключений
V>  Update(resNew, data);       // обновляем локальную копию, здесь будет 99% всех исключений

V>  // атомарно обновляем ссылку на данные, если до этого все прошло успешно
V>} while((currentTarget = Interlocked.CompareExchange(ref target, resNew, res)) != res); 
V>


1) Зачем ты это написал?
2) Где тут блокировка писателей?
3) Если писать в функциональном стиле именно такой код и получается.

Еще раз, что ты хочешь сказать?


G>>Не спорю. Но ты на вопрос ответь. Ты предлагаешь тестировать негативные сценарии, которые по сути не нужны пользователю. Зачем это делать?

G>>Ага, но если в десктопе писать большую часть приложения в таком же stateless стиле, то получается не хуже чем в вебе.

V>Не выйдет, ты же не только с данными работаешь, а со всем окружением вокруг программы, от которого изолирован в вебе. Если в вебе в случае ошибки ты отправил ее текс клиенту и "вышел", то в десктопе некуда выходить. Практически в КАЖДОМ сценарии тебе надо максимально адекватно обыграть любую ошибку. Без состояний на клиенте не обойтись. Напр, для твоего веба состоянием клиентской программы распоряжается браузер, + частично куки (хотя и тут гонки), и если для веба "нормально" показать ошибку и потерять нафик все результаты, например сообщение, которое тщательно 15 мин писал в этот форум прямо в браузере, то в обычной десктопной программе такое не прощается.

Ты не понял мысль. В десктопе можно точно также как в вед разделить state и логику. Логика stateless, state — это данные и интерфейс.
Логика будет "нейтральный по отношению к исключениям код", а изменение состояния интерфейса происходит только тогда когда отработала логика без ошибок. Естественно "сообщение которое писал 15 минут" не потеряется.
Обработка исключений будет сконцентрировала в PL, причем её можно не писать руками, а использовать runtime aop и policy injection для обработки.

V>А что я вижу порой и что имею ввиду? Такие лихие зацикливания в попытках "правильно" обработать ошибки в клиентских программах... В половине случаев в цикле начинают мне показывать сообщения об ошибке, избавиться от этого никак, только снять процесс. Помнится, первые версии решарпера это нам тоже демонстрировали во всей красе. Непервые ночные билды тоже. Это тебе дотнетная прога из первых рук. Или, например, программа работала нормально, но после первой же странной ошибки, стала показывать сообщения об ошибке на каждое действие. Я такого в нейтивных программах не помню оч. давно.


Нот, это происходит тупо потому что вставляют try\catch, который только и выводит сообщение, в итоге программа продолжает работать, но данные порушены и сразу же вылетает следующий exception итд. Причем от native\managed такое не зависит вообще, я видел подобно поведение и в программах на delphi, и на C++, и .NET или java.
Даже на курсах постоянно рассказываю истории про то что я видел именно в нативном коде на делфи. Там вообще ужос был с исключениями.


G>>Стейт как всегда присутствует в двух местах: интерфейс и хранилище данных. Первый нормально изолируется с помощью паттернов mv*, второй с помощью грамотно проработанных интерфейсов.


V>Ес-но, только у тебя "хранилище данных" — это и есть состояние твоей десктопной программы. С миллионном флагов и просто значений. И если ты сумеешь организовать транзакционность, т.е. чтобы обновление, скажем сотни полей, прошли либо все успешно, либо никто не прошел, то всё будет ок. Прямо как буд-то работаешь с транзакционной БД. О чем и речь. Просто в С++, ввиду того, что иногда приходится вручную следить, кто кем владеет и когда, безопасная схема слежения за ресурсами может быть только транзакционной или никакой. Устойчивость прикладной логики в этом случае — приятный бонус.


В .NET не надо схем городить, во-первых сборка мусора есть, во-вторых есть IoC-контейнеры, позволяющие централизовано управлять владением жизни объектов, в третьих писать логику надо с использованием immutable.

G>>Я десктоп практически не пишу, если пишу то это SL для веба или виндафона или же windows-сервисы. Везде подход оправдал себя. Вызывает иногда повышенный расход ресурсов, но зато никаких наведенных эффектов и приложения работают гораздо надежнее. А уже после разработки основного функционала нередко приходится заниматься оптимизацией, удается сократить время работы и затраты памяти на 20% просто конфигурированием ioc-контейнера и кешей.


V>Ну, если ты только клиента для БД пишешь, то у тебя тоже, большая часть сценариев сводится к staless, а транзакционность за тебя БД умеет.

А причем тут БД вообще? И что от того что она умеет транзакционность? Я вот видел "клиент для БД" который постоянно выдавал messagebox с ошибкой, причем он на вполне нативном delphi был написан.
Re[35]: Конец нересурсов
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.11.11 07:11
Оценка: :)
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, Геннадий Васильев, Вы писали:


G>>>Если же в реальном коде нет таких проблем как в указанном тобой примере, то зачем ты вообще писал пример?


ГВ>>По-видимому, я всё-таки невнятно это как-то обозначил: приведённый код принципиально однопоточный. Многопоточным он "становился" только из-за ошибки в управлении потоками.


V>Да это неважно. Оппонент старательно обходит утверждение, что ошибка на управляемой платформе "сглаживалась". Какая разница в подробностях, коль сие св-во платформы гарантируется алгоритмом GC? Ну и к тому же программисту под веб, как видно, предварительно надо объяснять, почему довольно большие куски программ порой пишут принципиально как однопоточные, где о лишней синхронизации не может быть и речи. А это уже за рамками обсуждения.


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

Надо не пытаться "бороться" с многопоточностью, надо убирать shared state из логики.
Re[38]: Конец нересурсов
От: vdimas Россия  
Дата: 23.11.11 07:39
Оценка:
Здравствуйте, samius, Вы писали:

V>>Пусть так. На C++, в отличие от, можно реализовать паттерн визитора в библиотечном виде. Я имею ввиду классический, который без тайп-тестов. И да, ни методы визитора, ни посещаемых объектов не обязаны быть виртуальными. По крайней сия библиотечная реализация не требует.

S>При отсутствии виртуальных методов и тайп-теста (либо его заменителей) мы не сможем работать с subtype-полиморфными данными. А именно это мне требовалось.

Это зависит от способа обхода целевого мн-ва. Иногда целевым является именно шаблонный код обхода, который оперирует разными типами, но находящимися в похожих отношениях. Ведь обход для целей визитора бывает внешний и инкапсулированный, это прямо в паттерне сказано. В случае инкапсулированного обхода необязательно всем элементам мн-ва быть наследником одного базового класса/интерфейса, это может быть лес независимых иерархий. Так вот, виртуальная точка входа для callMeBack() реально нужна только в том узле, реальный тип которого неизвестен. Тут уж, конечно, полиморфизм + DD помогут.

Поинт в том, что целевое мн-во объектов

V>>Цимус визитора в возможности расширения функциональности над семейством типов без изменения самого семейства, а остальные подробности несущественны.

S>Это известно.

S>>>www.cs.cmu.edu/~rwh/theses/okasaki.pdf (8.4 Queues and Deques)


V>>Предположим, что с основными структурами данных я знаком, и даже представляю, как они организуются в функциональной парадигме. У нас же был вполне конкретный вопрос по механике С++ и сравнении возможностей генериков из C#, для какого-то совсем конкретного момента реализации, который не был показан. ИМХО, реализаций любого абстрактного алгоритма может быть гораздо больше одной, поэтому почти всегда можно выкрутиться.

S>Естественно можем, но в случае с C++ придется ослабить типизацию, для того что бы работать с такой структурой в рантайме.

Во-первых, не вижу, откуда это следует. Во-вторых, там вообще работа по несчастным Cons, т.е. организации очереди на односвязанном списке, чтобы время доступа к обоим концам было O(n). Сорри, но я на коленке накатаю очередь, которая порвет эту многократно, и уж конечно будет тоже O(n). Бо мутабельный двусвязанный список всех описанных в той работе приседаний не требует... И там такой разный K при этом O(n) получается, что мама не горюй. Посмотри что происходит при двусторонней выборке. В общем, пусть у функциональщиков будут свои тараканы... ИМХО, в основу должны идти не алгоритмы, а требования. А уж алгоритмы берутся те, которые подходящие для инструмента, на котором мы решились эти требования удовлетворить.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.