Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с большим числом небольших объектов.  (Прочитано 24483 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ezus
Опытный

il
Offline Offline

« : 10-01-2011 12:25 » 

Добрай день!
В С# я начинающий.
В данный момент мы работаем над новой реализацией большого проекта на С++.
Модуль, с которым работаю я, работает с большим количеством мелких объектов, постоянно порождая у уничтожая их.
Оптимизируя старый проект, я заменил многочисленные new и delete на стек пулов памяти, что значительно увеличило производительность.

В связи с этим вопрос:
Есть ли смысл приминять в С# этот хорошо известный прием управления памятью?
Возможно есть другие подходы?
Или GC сам эффективно работает с сотнями тысяч (иногда миллионами) небольших объектов?

Спасибо.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 10-01-2011 14:30 » 

GC по-разному работает с большими и малыми по размеру объектами. На большие объекты (порядка Мб) он выделяет память специально под каждый отдельный объект. А малые объекты будто бы размещает внутри более крупных страниц памяти (по-твоему пулов).

Отсюда следует, что вручную такое делать не надо. Но ручаться не буду - не проверял. У GC, если не ошибаюсь, целых 4 разные политики управления памятью, которые отвечают как за распределение памяти, так и её дефрагментацию.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #2 : 12-01-2011 16:11 » 

Спасибо.
Будем экспкркминтировать.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 12-01-2011 17:00 » 

Коли заранее известно, что объекты мелкие и их будет много, то почему бы не сделать выделить сразу место под массив таких объектов? Например, сделать две функции типа my_object_new() и my_object_delete() и спрятать реализацию управления памятью туда.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 12-01-2011 20:22 » 

Последняя статья на сайте именно об этом... Трясти - не всегда лучший подход.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 12-01-2011 20:29 » 

Согласен, что сперва надо смотреть саму программу. Тем не менее подход не нов - пулы используются часто.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 12-01-2011 21:10 » 

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

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #7 : 13-01-2011 06:43 » new

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

Именно по этому в С++ и были использованы пулы, которые в ряде случаев дают выигрыш  в 8-10 раз.

Мои сомнения связаны с тем фактом, что в С++ я выделяю память одним большим куском сразу под 1000 объектов, в то время как в Сш , как я понимаю, память выделяется под референсы, а потом их все равно приходится заполнять через отдельные new.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 13-01-2011 06:53 » 

Вы уже читали статью https://club.shelek.ru/viewart.php?id=342 ?

Она как раз о подобных сомнениях и о надежных способах заменить их твердой уверенностью.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #9 : 13-01-2011 08:13 » 

Dale
Очень полезная статья, хотя я не нашел там практически ни чего нового, кроме примеров.
В моем курсе это называлось "Ложная оптимизация".
Но что интересно - все в мире повторяется.

Цитата: в статье
он обосновал это тем, что таким образом можно обнулить два указателя одной инструкцией записи двойного слова (это был мейнфрейм, а не x86), и разве это не разумная оптимизация?

В моей практике был удивительно похожий случай.
Было это в конце 70-х. Мы работали на Минск-32 и использовали некий стандартный пакет, для которого надо было писать ассемблерные вставки.
Однажды проходя мимо одной из моих сотрудниц (техника, даже не программиста), я краем глаза заметил на бланке кода что-то очень непривычное. Я попросил ее показать свой код. И оказалось, что она использует, ну, очень же специфическую команду, явно не ее уровня квалификации. При этом сама команда использовалась в очень нестандартном варианте. На вопрос зачем она это делает, я получил ответ, что этой одной командой она обнуляет 2 ячейки\слова сразу. Я ее сначала похвалил, а потом показал, что она на одном использовании этого приема выигрывает около 10 мксек. Но при обработке даже самого большого массива на 6 лентах (около 600000 записей), она получит выигрыш в 6 сек. Если для отладки этого приема ей придется выйти на машину (были такие времена) хотя бы на 1 раз больше (30 мин), то этот прием окупится очень не скоро, а с учетом того, что программа запускается раз в квартал, врядли мы вообще доживем до этого времени.

Прошу прошение за отступление.

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

Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 13-01-2011 08:58 » 

Так ведь именно об этом и речь - актуальность интересует, а измерения до сих пор не произведены.

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

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #11 : 13-01-2011 09:32 » 

Так ведь именно об этом и речь - актуальность интересует, а измерения до сих пор не произведены.

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

Простите, но чего-то не понимаю.

Оптимизируя старый проект, я заменил многочисленные new и delete на стек пулов памяти, что значительно увеличило производительность.
Необходимость оптимизации в этом месте - это не предположение, а уже проверенный и реализованный в С++ факт, подтвержденный измерениями.

Я правильно понял, что предлагается сначала написать в лоб, потом измерить, убедиться, что начальные подозрения оправдываются и только потом все переписать?



Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 13-01-2011 09:57 » 

Простите, но чего-то не понимаю.

Оптимизируя старый проект, я заменил многочисленные new и delete на стек пулов памяти, что значительно увеличило производительность.
Необходимость оптимизации в этом месте - это не предположение, а уже проверенный и реализованный в С++ факт, подтвержденный измерениями.

Простите, но теперь уже я перестаю понимать.

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

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

Здесь ситуация примерно та же. Механизмы распределения памяти у CRT и .NET совершенно различны, поэтому результаты прошлых измерений для C++ в приложении к программе на C# никакой ценности не представляют.

Я правильно понял, что предлагается сначала написать в лоб, потом измерить, убедиться, что начальные подозрения оправдываются и только потом все переписать?

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

Собственно, это наиболее простой пример борьбы с рисками - одной из основных дисциплин программной инженерии.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #13 : 13-01-2011 10:06 » 

No comment

Добавлено через 9 минут и 14 секунд:
Хотя нет.

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

Всегда ли в стартовом релизе надо использовать сортировку пузырьком, или уже зарание можно определить влияние алгоритма сортировки на производительность?
« Последнее редактирование: 13-01-2011 10:16 от ezus » Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 13-01-2011 10:43 » 

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

Я не предлагал мелкий локальный эксперимент.

Вопрос формулировался так:

Модуль, с которым работаю я, работает с большим количеством мелких объектов, постоянно порождая у уничтожая их.
...
В связи с этим вопрос:
Есть ли смысл приминять в С# этот хорошо известный прием управления памятью?
...
Или GC сам эффективно работает с сотнями тысяч (иногда миллионами) небольших объектов?

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

Всегда ли в стартовом релизе надо использовать сортировку пузырьком, или уже зарание можно определить влияние алгоритма сортировки на производительность?

Это зависит от степени проработки проекта. Если вы не знаете заранее, сколько данных нужно сортировать, вы не сможете оценить это влияние. Заложите быструю сортировку, а на деле окажется, что массив имеет 5 элементов. Такой вариант в статье тоже описывается.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #15 : 13-01-2011 11:05 » 

Ладно. Спасибо за разъяснения.

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

Очевидно, что с будующим проектом, как и с прошлым, будут и анализ производительности. и измерения. Просто. если ты знаешь, что так будет лучше, то почему бы сразу не проектировать так как надо?

А лекцию по принципах оптимизации я и сам могу прочитать.
Я обращался к опыту, которого у меня пока нет.
« Последнее редактирование: 13-01-2011 11:07 от ezus » Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 13-01-2011 11:22 » 

А лекцию по принципах оптимизации я и сам могу прочитать.

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

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
ezus
Опытный

il
Offline Offline

« Ответ #17 : 13-01-2011 11:44 » 

По поводу гаданий - это не ко мне.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #18 : 13-01-2011 14:26 » 

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

По моему, нет сомнений, что уничтожение и создание объектов, а также выделение памяти под них и работа сборщика мусора — все это добро есть время. Но, оптимизация нужна не всегда и не во всем: накладные расходы на оптимизацию могут перевесить работу всего вышеперечисленного добра. По этому требуется экспериментальная оценка. Оценка тоже нужна не всегда, т.к. это трудозатраты — сперва должна возникнуть существенная причина для этого.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 13-01-2011 14:56 » 

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

В связи с этим вопрос:
Есть ли смысл приминять в С# этот хорошо известный прием управления памятью?
Возможно есть другие подходы?
Или GC сам эффективно работает с сотнями тысяч (иногда миллионами) небольших объектов?

Спасибо.

Сборщик мусора в C# использует сложную стратегию, которая кардинально отличается от стратегии управления памятью в C++. В частности, объекты могут удаляться сразу, а могут болтаться до тех пор, пока объем мусора не превысит некий порог. Кроме того, объекты могут перемещаться в памяти для предотвращения фрагментации.

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

Реализовать пул в .Net можно - если вы точно знаете момент, когда объект никому более не нужен и может вернуться в пул. Но сборщик мусора для того и придуман, чтобы не заморачивать себе голову управлением времени жизни объектов.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
ezus
Опытный

il
Offline Offline

« Ответ #20 : 16-01-2011 08:55 » 

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

Еще раз - всем спасибо.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 16-01-2011 08:58 » 

ezus, ещё как возникало Улыбаюсь Но не в шарпе ))
Записан

ezus
Опытный

il
Offline Offline

« Ответ #22 : 17-01-2011 07:48 » 

ещё как возникало Улыбаюсь Но не в шарпе ))
А в шарпе?
Не было подходящих проектов, или в похожих проектах не возникло претензий к производительности по причине new / delete?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #23 : 17-01-2011 09:42 » 

ezus, Бог миловал, не было в шарпе больших проектов Улыбаюсь
Записан

ezus
Опытный

il
Offline Offline

« Ответ #24 : 17-01-2011 12:59 » 

Почти завидую
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 17-01-2011 13:47 » 

Как я понял, в практике участников форума не возникало потребности в управлении памятью.


Во "взрослом" .Net на декстопе/сервере - не возникало. Там вполне приемлемо работает стратегия "дешевой памяти".
Задуматься об управлении памятью пришлось в Compact Framework для мобильных устройств. Там и память лимитирована, и сборщик мусора работает своеобразно. Использовались несколько подходов.
1. Объект для хранения результата создает вызывающая сторона, вызываемая функция записывает результат туда. Это позволяет здорово сэкономить на создании-удалении временных объектов.
2. Вместо конкатенации использовать буферизацию.
2.1 вместо a+b+c писать result.clear().append(a).apend(b).append(c) - экономия на создании временного объекта a+b. В таком простом примере экономия не видна, однако при сложении в цикле может быть существенна.
2.2 вместо f()+g()+h() писать f(buf);g(buf);h(buf); - экономия на создании временных объектов для хранения результатов функций f(), g() и h(), а так же их сумм.
3. Повторное использование памяти в вызовах Plaform Invoke - но этот рецепт требует большой аккуратности, так как может привести к тяжелым последствиям.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
ezus
Опытный

il
Offline Offline

« Ответ #26 : 17-01-2011 15:44 » 

npak
Это немного не те проблемы, но за советы Большое Спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines