Здравствуйте, DarthSidius, Вы писали:
DS>Выполни код:
Console.WriteLine("{0:C} {1:C}", 2.225m, 2.235m);
DS>
По практическим соображениям еще интереснее как механизмы System.Data.OleDb работают при записи в sql'ные поля decimal(n,2). Как-нибудь при случае проверю
Здравствуйте, Sinix, Вы писали:
I>>Ты сказал следующее "других вариантов без unmanaged нет". Вот я и думаю, как это относится к Pile ? Вот он умеет хранить миллиард строк. S>Дык неэффективно же, через сериализацию. Вдобавок, сами сегменты хранятся как managed byte[] и по-прежнему создают нагрузку на GC.
Время по профайлеру не выходит за определеные рамки, 15-30mc. Это про Pile. Стало быть с нагрузкой все в порядке — она под контролем.
S>Нутуткак... с "мы не смогли в GC" возможны ровно два варианта: S>1. Люди не читали матчасть, пока не стало поздно. За такими постами имеет смысл следить только ради "смотри, как делать не надо". Потому что если читать — подобные приседания за очень редкими исключениями не нужны. У вас же получилось
Не пойму, чего именно у меня получилось, не смочь в гц, следить за постами или редкое приседание ?
S>2. У людей реальный large scale и они на нём съели собаку. Как правило, таких постов не бывает, ибо NDA и не дураки дарить такой подарок конкурентам. Исключений очень мало, ссылки поприводил постом выше.
Опенсорс никто пока не отменял. Если замеров нет, то согласно книге, на которую ты ссылался, нет оснований утверждать что одно другого быстрее. Или не так ?
I>>Насколько buffer pool будет быстре Pile ? Есть какие сравнения? S>Сам по себе — одинаково. Выигрыш будет за счёт отсутствия сериализации
И тут снова не ясно, каким чудом хранить строки без этой самой серилизации в managed варианте
I>Время по профайлеру не выходит за определеные рамки, 15-30mc. Это про Pile. Стало быть с нагрузкой все в порядке — она под контролем.
Это неимоверно много. Сопоставимо с worst case для realtime gc или с обычными in-mem db (как пример — Redis или VelocityDB). Нынче в моде 10e6 rps, какие миллисекунды?
Тем более для классической CDN-задачи, по крайней мере текущее обсуждение всё больше в эту сторону сворачивает.
S>>1. Люди не читали матчасть, пока не стало поздно. За такими постами имеет смысл следить только ради "смотри, как делать не надо". Потому что если читать — подобные приседания за очень редкими исключениями не нужны. У вас же получилось I>Не пойму, чего именно у меня получилось, не смочь в гц, следить за постами или редкое приседание ?
Не, в том смысле, что у тебя всё сработало без приседаний с unmanaged-пулом.
I>И тут снова не ясно, каким чудом хранить строки без этой самой серилизации в managed варианте
Ну так не надо стандартные строки пихать куда не лезут. Свой стек аля Text.Formatting и вперёд. Ну да, hiperf небесплатный и никогда им не был, какие ещё варианты могут быть-то?
Здравствуйте, Sinix, Вы писали:
I>>Время по профайлеру не выходит за определеные рамки, 15-30mc. Это про Pile. Стало быть с нагрузкой все в порядке — она под контролем. S>Это неимоверно много. Сопоставимо с worst case для realtime gc или с обычными in-mem db (как пример — Redis или VelocityDB). Нынче в моде 10e6 rps, какие миллисекунды?
Миллиард строк здесь нигде не фигурирует. Вобщем, если других замеров нет, то можно и закончит
Здравствуйте, Don Reba, Вы писали:
DR>Здравствуйте, Win32nipuh, Вы писали:
W>>А смысл это все иметь в памяти? W>>Почему бы не использовать, например,SQLite ?
DR>Вопрос был о самых быстрых коллекциях, а не о самых медленных.
SQLite может хранить всю свою базу только в памяти.
Единственный нюанс, если мне не изменяет склероз, писать в нее обязательно надо в транзакции (в противном случае, на каждую запись SQLite сама открывает/закрывает транзакцию).
Здравствуйте, sn175, Вы писали:
S>Здравствуйте, Don Reba, Вы писали:
DR>>Здравствуйте, Win32nipuh, Вы писали:
W>>>А смысл это все иметь в памяти? W>>>Почему бы не использовать, например,SQLite ?
DR>>Вопрос был о самых быстрых коллекциях, а не о самых медленных.
S>SQLite может хранить всю свою базу только в памяти. S>Единственный нюанс, если мне не изменяет склероз, писать в нее обязательно надо в транзакции (в противном случае, на каждую запись SQLite сама открывает/закрывает транзакцию).
Про транзакции не скажу, но соединение необходимо постоянно держать открытым. Вообще говоря, sqlite, даже в памяти, не самое лучшее решение для данной задачи, ибо оверхед на доступ к данным все же есть. Хотя надо мерить и смотреть, но навскидку кажется, что это не самый быстрый вариант.
S>>SQLite может хранить всю свою базу только в памяти. S>>Единственный нюанс, если мне не изменяет склероз, писать в нее обязательно надо в транзакции (в противном случае, на каждую запись SQLite сама открывает/закрывает транзакцию).
S>Про транзакции не скажу, но соединение необходимо постоянно держать открытым. Вообще говоря, sqlite, даже в памяти, не самое лучшее решение для данной задачи, ибо оверхед на доступ к данным все же есть. Хотя надо мерить и смотреть, но навскидку кажется, что это не самый быстрый вариант.
Надо мерить. Навскидку, чем сложнее выборка тем предпочтительней sqlite. Да и кода писать сильно меньше.
Здравствуйте, sn175, Вы писали:
S>Здравствуйте, Sharov, Вы писали:
S>>>SQLite может хранить всю свою базу только в памяти. S>>>Единственный нюанс, если мне не изменяет склероз, писать в нее обязательно надо в транзакции (в противном случае, на каждую запись SQLite сама открывает/закрывает транзакцию).
S>>Про транзакции не скажу, но соединение необходимо постоянно держать открытым. Вообще говоря, sqlite, даже в памяти, не самое лучшее решение для данной задачи, ибо оверхед на доступ к данным все же есть. Хотя надо мерить и смотреть, но навскидку кажется, что это не самый быстрый вариант.
S>Надо мерить. Навскидку, чем сложнее выборка тем предпочтительней sqlite. Да и кода писать сильно меньше.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Ikemefula, Вы писали:
I>>А за счет чего gc исключается ? Вот надо хранить миллиард строк. Как это будет храниться в пуле ?
S>1. Храним структуры. S>2. Структуры храним в массиве из пула. Нужен динамический размер — собираем список из сегментов из пула.
S>Ну да, оно очень ограничено по сценариям использования, да и произвольные структуры данных поверх так просто не построишь, но у NFX Pile ровно те же проблемы.
У Pile нет таких проблем. Вы можете хранить objects предметнои области (еслу толко в них нет unmanaged handles) без модификации
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Ikemefula, Вы писали:
I>>Похоже, кого то вопрос задел за живое. Так и говори — никак.
S>Не угадал. Смысл повторять то, что уже отвечал, да ещё и без сарказма? Скучно же.
S>Я всё расписал в стартовом ответе, если потерял нить обсуждения:
S>А. Только managed code S>* используем buffer pool, выделяем из него сегменты, наворачиваем поверх коллекцию или stream, заполняем структурами. Vladek выше давал ссылку на RecyclableMemoryStream, там в документашке всё есть как бы. S>* других вариантов без unmanaged нет. Надо объяснять почему?
S>Б. Количество сегментов настолько большое, что они сами по себе создают gc pressure. Правда, для этого надо выделить гигов эдак 10-20 (считаем сегменты в 65к), активно насиловать gen2 и использовать client gc, т.е. быть полным злым буратиной.
S>Ну ок, лечится элементарно: перекидываем буферы в MMF/свой unmanaged pool.
S>В. Объекты не влезают в память. Тут как бы очевидно — любая in-process db/distributed cache (смотря по обстоятельствам)
S>Собственно вопрос на миллион долларов: куда тут приткнуть pile? И нафига дёргаться _до_ момента, когда мы действительно уткнёмся в GC?
I>>Спасибо, но я не спрашивал у тебя советов, как разгрузить GC. Давать советы, когда тебя не просили — хамство. S>Ну да, любой врач, который лечит болезнь, а не жалобы по определению хам. Так и живём
S>Ну и поскольку я сегодня добрый, я не буду напоминать про "К слову, физической памяти у твоего процесса никогда столько не будет". Хотя надо бы
Pile pritknut suda, kogda nado xranit sotni millionov social connections i so skorostijy 5,000,000 /sec delat' lookup. Pri etom mojno xranit' predmetnie objects: Person, Friend, List<Friend> a ne special kakie to structures
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, Sinix, Вы писали:
I>>>Ты лучше расскажи, как именно в buffer pool будет храниться миллиард строк. Мне непонятно, что значит "выделяем сегменты", "наворачиваем коллекции", "заполняем структурами"
S>>Вот именно за этим я и отослал к книжке Бена Ватсона. Смысл обсуждать сложные вещи, если надо сперва пересказать азбуку оптимизации по хардкору?
I>Ты сказал следующее "других вариантов без unmanaged нет". Вот я и думаю, как это относится к Pile ? Вот он умеет хранить миллиард строк.
S>>Ну, т.е. любая попытка объяснения сведётся к тому, что сначала надо будет объяснять более базовые вещи и так до Рихтера.
I>Если что, я с товарищами несколько лет кряду оптимизировал приложение, где было конское количество объектов, до 100КК разных виртуальных вычислимых объектов. И это работало очень достойно, при чем в 32х бит приложении. Я правда не дошел до серилизатора и ММФ, думал слишком медленно будет. Однако, все сильно. Но вот интересно, как люди ухитряются тотально сбороть GC в миллиардах объектов.
S>>Смысл такой: у тебя есть возможность динамически аллоцировать/освобождать сегменты (массивы определённой длины) без создания дополнительной нагрузки на GC — освобождённые инстансы забираются обратно в пул. Количество этих сегментов — пока не исчерпается адресное пространство процесса / VM.
I>Ок, наворачивать == аллоцировать/освобождать. Тогда строки хранить побайтно этих сегментах. В итоге получится тот же Pile, только менее универсальный, но более быстрый. I>Насколько buffer pool будет быстре Pile ? Есть какие сравнения ?
Vy mojete xranit v Pile byte[] — ine delat serializaiju. No eto marazm. Prakticheski Pile daet realno na nashem production servere 3,000,000/lookups v secundu is kotoryx 2M+ hits.
Pile idealene dlya sozialnix sitov i proscheta slojnix grafov, kogda nodes ne chasto menautysa
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Ikemefula, Вы писали:
S>>>Вот именно за этим я и отослал к книжке Бена Ватсона. Смысл обсуждать сложные вещи, если надо сперва пересказать азбуку оптимизации по хардкору? I>>Ты сказал следующее "других вариантов без unmanaged нет". Вот я и думаю, как это относится к Pile ? Вот он умеет хранить миллиард строк. S>Дык неэффективно же, через сериализацию. Вдобавок, сами сегменты хранятся как managed byte[] и по-прежнему создают нагрузку на GC.
S>Если уж и упарываться с "мы пойдём своим путём", то как-то так.
I>>Если что, я с товарищами несколько лет кряду оптимизировал приложение, где было конское количество объектов, до 100КК разных виртуальных вычислимых объектов. И это работало очень достойно, при чем в 32х бит приложении. Я правда не дошел до серилизатора и ММФ, думал слишком медленно будет. Однако, все сильно. Но вот интересно, как люди ухитряются тотально сбороть GC в миллиардах объектов.
S>Нутуткак... с "мы не смогли в GC" возможны ровно два варианта: S>1. Люди не читали матчасть, пока не стало поздно. За такими постами имеет смысл следить только ради "смотри, как делать не надо". Потому что если читать — подобные приседания за очень редкими исключениями не нужны. У вас же получилось
S>2. У людей реальный large scale и они на нём съели собаку. Как правило, таких постов не бывает, ибо NDA и не дураки дарить такой подарок конкурентам. Исключений очень мало, ссылки поприводил постом выше.
I>>Ок, наворачивать == аллоцировать/освобождать. Тогда строки хранить побайтно этих сегментах. В итоге получится тот же Pile, только менее универсальный, но более быстрый. I>>Насколько buffer pool будет быстре Pile ? Есть какие сравнения? S>Сам по себе — одинаково. Выигрыш будет за счёт отсутствия сериализации (в обмен на заметное усложнение работы с произвольными структурами, да). Чтоб кто-то сравнивал — сомневаюсь, не настолько популярная тема, чтоб имело смысл бенчмарки лепить.
Pile is open source. What NDA are you talking about? We keep hundreds of millions of social connections in ram in production cheers
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Ikemefula, Вы писали:
I>>Время по профайлеру не выходит за определеные рамки, 15-30mc. Это про Pile. Стало быть с нагрузкой все в порядке — она под контролем. S>Это неимоверно много. Сопоставимо с worst case для realtime gc или с обычными in-mem db (как пример — Redis или VelocityDB). Нынче в моде 10e6 rps, какие миллисекунды?
S>Тем более для классической CDN-задачи, по крайней мере текущее обсуждение всё больше в эту сторону сворачивает.
S>>>1. Люди не читали матчасть, пока не стало поздно. За такими постами имеет смысл следить только ради "смотри, как делать не надо". Потому что если читать — подобные приседания за очень редкими исключениями не нужны. У вас же получилось I>>Не пойму, чего именно у меня получилось, не смочь в гц, следить за постами или редкое приседание ? S>Не, в том смысле, что у тебя всё сработало без приседаний с unmanaged-пулом.
I>>И тут снова не ясно, каким чудом хранить строки без этой самой серилизации в managed варианте S>Ну так не надо стандартные строки пихать куда не лезут. Свой стек аля Text.Formatting и вперёд. Ну да, hiperf небесплатный и никогда им не был, какие ещё варианты могут быть-то?
Voobshe neponyatno chto vy sravnivaete. Kakoi Redis? Vam Redis dast original "Person" ili storku kotoruju nado parsit?
Pile legko daet 2+M cache hits/sec i pri etom CPU <25%. Eto uje objekti predmetnoi oblasti a ne string.
Stringi pile mojet dat 10,000,000/sec , no eto stroki. Unmanaged pool nichem ne pomojet ibo v nem nevozmojno xranit objekti predmetnoi oblasti prosto tak.
Mojno sdleat spezialnoe xranilishe na C++ i xranit naprimer Person v unmanaged pamyati, no eto ochen slojno i ne opravdano. A chto esli mne nado pomenyat polya v Person?
Pile kak raz nujen dlya togo chtobi xranit DOMAIN OBJECTS. Realno, nash HTTP MVC stack + filters+security+CSRF etc.. tyanet okolo 50,000 req/sec — eto soljnix business zaprosov, s traversingom
sozialix svazei druzei, inogda po 10 chelovek vglub'.
Здравствуйте, itadapter, Вы писали:
S>>Ну да, оно очень ограничено по сценариям использования, да и произвольные структуры данных поверх так просто не построишь, но у NFX Pile ровно те же проблемы.
I>У Pile нет таких проблем. Вы можете хранить objects предметнои области (еслу толко в них нет unmanaged handles) без модификации
Привет!
Судя по количеству ответов, не только Ikemefula не читал стартовый пост
привет
Работаю с биржевыми данными
данных много — 30 000 000 экземпляров записей
в каждом экземпляре есть поле — цена — тип Double
необходимо иметь быстрый доступ к экземпляру по цене
Ну т.е. у человека проблема непонятно в чём, но скорее всего не в GC (вот тут пошло отступление в сторону раз) и уж точно не в
Итого, все это постоянно кочует между виртуальной(свопом) и физической памятью.
С учётом комментария топикстартера про "25 гб в пике" — проблема в первую очередь в "никто perf metrics не заморачивался".
Но это я уже к остальным комментаторам присоединяюсь, диагностика по фото такая диагностика
Я в этот праздник жизни старался не вмешиваться, единственно, постарался ответить, почему _в данном конкретном случае_ Pile не лучший выбор и лучше подобрать альтернативу.
Разобрались?
Здравствуйте, Sinix, Вы писали:
I>>У Pile нет таких проблем. Вы можете хранить objects предметнои области (еслу толко в них нет unmanaged handles) без модификации
S>
S>привет
S> Работаю с биржевыми данными
S> данных много — 30 000 000 экземпляров записей
S> в каждом экземпляре есть поле — цена — тип Double
S> необходимо иметь быстрый доступ к экземпляру по цене
S>Ну т.е. у человека проблема непонятно в чём, но скорее всего не в GC
Вообще то замеры показывают, что 30КК в Gen2 дают жесточайшие лаги GC. У ТС реально намного больше объектов в рантайме, ибо речь про записи, а сколько всего объектов можно только предположить основываясь на тех самых 25гб в пике.
S>С учётом комментария топикстартера про "25 гб в пике" — проблема в первую очередь в "никто perf metrics не заморачивался".
25гб в пике уже наводит на мысль, что с ГЦ нужно замерить в первую очередь. Не то записи конского размера, не то на каждую запись по десятку вспомогательных объектов. Ну не умеет ГЦ такие объемы обрабатывать. Он на 10млн уже начинает тупить.
S>Я в этот праздник жизни старался не вмешиваться, единственно, постарался ответить, почему _в данном конкретном случае_ Pile не лучший выбор и лучше подобрать альтернативу. S>Разобрались?
Если замеров внятных не было, счетчиками никто не заморачивался, то совершенно не ясно, откуда проблемы. Может дело вообще не в ГЦ, а может и в ГЦ — замеров то нет. Без них что либо утверждать, лучший выбор или не лучший — чисто шаманский подход и танцы с бубном.
Здравствуйте, Ikemefula, Вы писали:
I>Вообще то замеры показывают, что 30КК в Gen2 дают жесточайшие лаги GC. У ТС реально намного больше объектов в рантайме, ибо речь про записи, а сколько всего объектов можно только предположить основываясь на тех самых 25гб в пике.
Это всё диагностика по фотографии. В корректно написанном софте GC2 может не происходить днями, а если и срабатывать, то практически не оказывать эффекта из-за <gcConcurrent/> (в 4.5+). На крайний случай, нагрузка может скидываться на другие машины в ответ на GC.RegisterForFullGCNotification(). В общем, смотреть надо.
I>Если замеров внятных не было, счетчиками никто не заморачивался, то совершенно не ясно, откуда проблемы. Может дело вообще не в ГЦ, а может и в ГЦ — замеров то нет. Без них что либо утверждать, лучший выбор или не лучший — чисто шаманский подход и танцы с бубном.
Бинго!
Сначала диагностика, потом лечение. Порядок важен.
Здравствуйте, Albeoris, Вы писали:
I>>Поле цена это просто поле цена. Я например год работал на проекте, где лет пять до того цену хранили даблом. И никаких проблем с погрешностью не было. Не просто никаких, а абсолютно никаких. I>>Так что не все вычисления можно и нужно относить к 'финансовым'. A>Ты ведь зачем-то используешь double вместо float. То есть какая-то зависимость от погрешности есть.
7 точных цифр недостаточно даже для записи суммы вроде $987654.32 — которые реально бегают по миру.
16 цифр всё-таки (пока) достаточно для происходящего в современных финансах, даже с учётом необходимости запаса в как минимум одну цифру на округление.
Проблема double и вообще двоичных представлений в другом — обсуждалось, например, совсем недавно
.
A>Умные люди в больших проектах на таких вот ошибках вычисления с плавающей точкой делают хорошие деньги, выводя из оборота тысячные доли копеек.
Это только при отсутствии минимального контроля кода, даже коллегами по разработке, а тем более сторонней организацией (которую к таким серьёзным задачам таки надо привлекать), и на специфических задачах (ну где сейчас делят сумму, например, на 3 равные части? в основном идёт сама сумма и оплата за перевод).
Скорее всего эта история из 70-х больше не воспроизводилась, и все более поздние упоминания её как реальной — просто байки. (Готов сделать поправку на экзотические места вроде Индии, где повторяют проблемы IT со сдвигом на 20-30 лет.)
A>Кроме того GetHashCode() вычисляет хэш по байтам double'а (приводя Double* к Int64*), а, значит, ошибка с плавающей точкой приведёт тебя к тому, что ты не сможешь найти значение в словаре по указанному значению (будет 9,99999999999998 вместо 10.0 и т.д.).
Даже с учётом экзотичности подхода ТС (ну какой словарь по цене? а если она совпадает у акций десятков тысяч разных фирм?), цена, если она взята из нормального источника, представляет собой значение, максимально точно представляющее десятичную реальную цену.
Вот качество подобного приведения — вопрос более интересный — вдруг в разных библиотеках это сделано по-разному.
Но у Вас тут допущение, которому я не вижу нигде в треде обоснования — почему вдруг _хэш_??? Тут полезен только поиск от точной цены на некоторый диапазон вбок. Следовательно, задача нормально ложится только на std::multimap (в терминах C++); не вижу аналога для дотнета — наверно, надо брать сторонние решения. SortedDictionary с массивом значений не годится из-за отсутствия перехода к соседним значениям (как higherEntry, lowerEntry у NavigableMap в Java), если это не достигается хитрой оптимизацией Min/Max с ограничениями.
A>Но я всё же рекомендую переосмыслить подход к индексации записей.