Pull to refresh
8
0
Send message
Как-то даже в голову не приходило. Попробовал сейчас прикрутить — как-то не ложиться совсем AsyncEnumerator на задачу. А в целом, хоть и не знаком с SyncGate, думаю, что один локер чтения/записи Рихтера вряд ли окажется сильно лучше другого похожего локера Рихтера. Но интереса ради всё равно попробую.
Нет смысла при 80%. Объект исследования — эффективность параллельных операций записи/чтения в коллекции, а не необходимость использования словаря. На практике большинство операций — чтение по ключу. Однако только ими обходиться утопчино. Можно представлять кэш в виде нескольких коллекций, заточнных под конкретную операцию, как вы предлагаете. Даже иногда нужно. Но это требует затрат на синхронизацию, повышает сложность и не всгегда таким образом можно покрыть 100% случаев.
Измерялся не сам Dictionary, а его применение в качестве кэша таблиц-справочников. Для них, к сожалению, приходится использовать итератор — тут и поиск нужен, и запрос всех значений. Например, для того чтобы отобразить все элементы для редактирования — нам нужен запрос всех значений. Поиск может понадобиться, например, для фильтра по ParentId. А удаление устаревших это несколько в другую степь — здесь именно справочник, синхронизированный с таблицей в БД.
Ну вроде по хорошему так и должно быть, не в 3 раза конечно, но профит должен быть. Собственно по слиму мой основной вывод — я не умею его готовить. Либо его оптимально использовать в каких-то сложных ситуациях. Возможно, кто-то найдёт в исходниках соль проблемы. Но он в любом случае по своей сути не будет быстрее ConcurrentDictionary. Да и OneManyResourceLock наверняка пооптимальнее.
dictionary.FirstOrDefault(..) например, или dictionary.Values.ToArray(). Такие операции будут отрабатывать значительно дольше нежели просто чтение данных по ключу. Собственно на графике нарисовано — насколько дольше. Вот таблица с полными данными — yadi.sk/d/n5ycSsDf0O3Sf (в статье ссылка тоже есть).
Я имел в виду, что если с такой прорвой данных будут активно работать, то ConcurrentDictionary хотя бы не зависнет в локе намертво, поскольку ему не требуется блокировка для чтения. А насчёт интовского ограничения длины, разумеется, с вами согласен. И не менее согласен насчёт подзатыльников.
Да, это главный недостаток подхода с кэшем словарей в целом.
У нас запись в кэш происходит только после успешного завершения транзакции. Это решает проблему с незавершёнными транзакциями, но не решает проблему того, что порядок выполнения транзакций и порядок записи в кэш могут различаться.
На текущий момент для нас это проблемой не является — то, что кэшируется, редактируется довольно редко. Пока что можем позволить себе такую волность — релиз ещё не выпускали (делаем новую версию продукта). Но что-то делать с этим будем обязательно. Как вариант могу предложить решение с синхронизацией записи в кэш в соответствии с временем завершения транзакции.
Для отдельного элемента — да. Благодаря линкед-листам ConcurrentDictionary позволяет использовать итератор без блокировки (т.е. одновременно с записью). Эту же задачу, в целом, решает и CopyOnWrite.
А слабые ссылки позволяют избегать утечек при реализации, т.е. прямого отношения к задаче не имеют.
А этих ребят (MemoryCache, ObjectCache) я тоже пробовал — не вписываются в задачу, там и контракт не удобный и время работы не ахти. Всё же их основное назначение обеспечение времени жизни элементов кэша.
Здесь растёт доля не всех операций чтений, а только по значению. Операций чтения здесь фиксированно 20%, указанная доля по поси X — доля чтения по значению, то что остаётся — чтение по ключу. Околонулевое время при 0% чтения по значению объясняется малым количеством операций в тесте — получается что запись/чтение по ключу отрабатывает мгновенно. Если увеличить количество операций — увидим ту же картину, но с большими числами, соответственно в нуле будет не 0 по Y, а некое число побольше.
Согласен. Такие средства нужны для относительно компактных словарей. А большим данным — большие решения. И, да, без заточки решения под себя, тоже считаю, в этом случае не обойтись.
Не измерял, но теоретически ConcurrentDictionary как-то работать будет. А вот словари с блокировкой помрут я думаю. В принципе это уже несколько иная задача и надо использовать другие средства — не думаю, что гонять итератор по много-гигабайтному словарю хорошая идея.
Там измеряли сами блокировки чтения и записи по отдельности. И они естественно проиграли простому как репа монитору. Здесь же чтение и записть происходит одновременно, что позволяет ReaderWriterLocker'у получить преимущество над монитором.
В статье рассматривались только стандартные решения для .NET. Ссылку на исходники я выложил — можно реализовать свой обработчик операций и протестировать. Если речь о проектировании нашего сервера — это офтопик, не хочу вступать в холивары. На данный момент по ряду причин нам больше подходит то решение, которое реализовано.
Насколько я знаю, у него как киллер-фича (в отличие от простого ReaderWriterLock) декларировалось то, что по умолчанию выключена поддержка рекурсии, что вроде как должно издержки снижать. Но что-то у меня не получилось с ним подружиться — возможно профит заметен если использовать собственно рекурсию или апгрейды ридера на райтер (которые вроде как тоже улучшались).
Вы о LockRecursionPolicy? В приведённых тестах — дефолтная. Пробовал и NoRecursion и SupportsRecursion — разницы нет, в принципе рекурсия то и не используется.
Коллега, а что означает опция «заморозить расположение» на самом первом скриншоте?

Еще хочу обратить внимание, что при количестве автомобилей даже 10 (не говоря уже о 200) пользователю очень пригодился бы групповой отчет по топливу. Сейчас, при попытке построить отчет по нескольким автомобилям, АТ-Наблюдатьель кричит на пользователя:
image
Не гуманно…

P.S.: Может быть Вы предложите ссылку на демо-версию?
Обратите внимание на результаты Ublox, который тестировался в режиме «только ГЛОНАСС».
Цель указана в моем комментарии повыше. Действительно, отличия не значительные, но лидеров выявить нам удалось.
Спасибо за ваши комментарии. Так сложилось, что наших заказчиков интересует не «истинное положение вещей» без учета фильтра Калмана, а что бы «машинки через дома не летали». Поэтому и проводили реальную обкатку и выводы делали операясь на повторяемые аномалии на треке на скольких приборах.
1

Information

Rating
Does not participate
Registered
Activity