Comments 22
А что сохраняется — тупо текущее состояние? История правок (с возможностью undo) не сохраняется? Что происходит при крэше приложения/ОСи?
Я как бы намекаю на одно типовое решение…
Я как бы намекаю на одно типовое решение…
+1
Странное сравнение:
Если уж сравнивать sqlite и nosql, то логично (по-моему) в случае с sqlite
использовать sqlite json extension,
или в C# обертку для sqlite json еще "не завезли"?
- По поводу времени "write" для sqlite, хотелось бы увидеть какой journal mode sqlite
использовался, какой его аналог в LiteDB, сколько транзакций во время записи было
в случае sqlite и LiteDB
+1
Не очень пойму как мог бы помочь sqlite json extension. Это ведь набор функций для работы с json или я не прав?
Если это действительно всего лишь набор функций, то думаю еще бы потерял в скорости, генерируя для вставки в базу из текста json, а потом разбирая его, пусть даже последним бы и занималась SQLite. SQLite реляционная база и я ожидал от нее наибольшей производительности именно если складывать в нее реляционные данные.
Режим журналирования SQLite: PRAGMA journal_mode = OFF
Использовал по транзакции на файл.
Так же и litedb все льется одним insert'ом, что, пусть и с натяжкой, с натяжкой можно считать одной транзакцией.
Если это действительно всего лишь набор функций, то думаю еще бы потерял в скорости, генерируя для вставки в базу из текста json, а потом разбирая его, пусть даже последним бы и занималась SQLite. SQLite реляционная база и я ожидал от нее наибольшей производительности именно если складывать в нее реляционные данные.
Режим журналирования SQLite: PRAGMA journal_mode = OFF
Использовал по транзакции на файл.
Так же и litedb все льется одним insert'ом, что, пусть и с натяжкой, с натяжкой можно считать одной транзакцией.
0
Сферические цифры по сохранению несложных POCO объектов (диск hdd):
[Serializable]
public class MscEvent
{
public Int64 msisdn;
public DateTime chargingdatetime;
public Int64 chargeableduration;
public Int64 bnumber;
public Int16 typeofrecord;
public Int16 sourceId;
}
Testing on 1 000 000 events
[Sqlite Journal Mode=Off] write/read 89462/287835 op/s] time elapsed write/read 11,1778348 / 3,4742009 s]
[LevelDbBatch MsgPackSerializer NoCompression] write/read 178024/501050 op/s] time elapsed write/read 5,6172074 / 1,995808 s]
[LiteDb] write/read 82346/218760 op/s] time elapsed write/read 12,1438787 / 4,5712058 s]
[CsvBench] write/read 749532/392383 op/s] time elapsed write/read 1,3341648 / 2,5485245 s]
[SerializedFile MsgPackSerializer] write/read 2193977/675174 op/s] time elapsed write/read 0,4557931 / 1,4810979 s]
[SerializedFile JsonSerializer] write/read 301375/317855 op/s] time elapsed write/read 3,3181228 / 3,1460794 s]
[SerializedFile WireSerializer] write/read 2214939/2129023 op/s] time elapsed write/read 0,4514795 / 0,4696988 s]
Testing on 10 000 000 events
[Sqlite Journal Mode=Off] write/read 89674/285626 op/s] time elapsed write/read 111,514258 / 35,0107894 s]
[LevelDbBatch MsgPackSerializer NoCompression] write/read 136594/488647 op/s] time elapsed write/read 73,2091265 / 20,4646613 s]
[LiteDb] write/read 75120/196484 op/s] time elapsed write/read 133,1192939 / 50,8947216 s]
[CsvBench] write/read 709238/398380 op/s] time elapsed write/read 14,099631 / 25,10166 s]
[SerializedFile MsgPackSerializer] write/read 1533240/673520 op/s] time elapsed write/read 6,5221352 / 14,8473537 s]
[SerializedFile JsonSerializer] Необработанное исключение: OutOfMemoryException.
[SerializedFile WireSerializer] write/read 1567601/2205764 op/s] time elapsed write/read 6,3791707 / 4,5335747 s]
C leveldb пробовал разные параметры компрессии, буферов и т.д. (например new Options() {Compression = CompressionType.SnappyCompression, WriteBufferSize = 128*1024*1024}
)
Вообщем вот. Выводы делайте сами
+1
Мой тест имел кое-какую специфику, о которой я писал:
Мы храним текст построчно, а значит хотим и сохранять и вычитывать тоже построчно. К тому же при вычитке одним куском рискуем нарваться на огромный memory allocation, и нарваться на него же при сохранении, если для этого нужно склеить все строки вместе. В LiteDB есть возможность скормить IEnumerable и он отлично сохранится, и отлично вычитается. В SQLite строка в документе представляла собой строку в базе. Получается для документа в 100 строк, выполнялось 100 инсертов, что было дольше чем выполнить 1 в LiteDB.
Мы храним текст построчно, а значит хотим и сохранять и вычитывать тоже построчно. К тому же при вычитке одним куском рискуем нарваться на огромный memory allocation, и нарваться на него же при сохранении, если для этого нужно склеить все строки вместе. В LiteDB есть возможность скормить IEnumerable и он отлично сохранится, и отлично вычитается. В SQLite строка в документе представляла собой строку в базе. Получается для документа в 100 строк, выполнялось 100 инсертов, что было дольше чем выполнить 1 в LiteDB.
0
А в сторону ESENT не смотрели? По скорости быстрее, чем SQLite.
+2
Как-то в Сети не почти ничего про эту технологию. Можете рассказать или навести на правильные ссылки?
0
https://en.wikipedia.org/wiki/Extensible_Storage_Engine
https://blogs.msdn.microsoft.com/windowssdk/2008/10/22/esent-extensible-storage-engine-api-in-the-windows-sdk/
для c#
https://www.nuget.org/packages/ManagedEsent/
https://blogs.msdn.microsoft.com/windowssdk/2008/10/22/esent-extensible-storage-engine-api-in-the-windows-sdk/
для c#
https://www.nuget.org/packages/ManagedEsent/
+1
Это низкоуровневый ISAM движок, который раньше
ESENT очень широко используется внутри самой Windows, это нативное win32 API со всеми последствиями, но есть обёртка под .NET и работает это решение даже на WindowsPhone и в UWP приложениях (Даже в плеере Zune в качестве БД использовался ESENT). Потребляет больше памяти чем SQLite, но и больше функционал (снапшот изоляция транзакций, полное журналирование, и т.д.). Из минусов пишут такое: «своеобразные требования к thread-ингу. Приложение может открыть сколько угодно параллельных сессий. Но одна сессия должна жить в рамках одного треда.»
И до 7ки он вроде как был жестко прибит гвоздями к NTFS и зависел от размера кластера, но потом отвязали от NTFS.
https://www.codeproject.com/articles/52715/extensible-storage-engine
https://msdn.microsoft.com/en-us/library/gg269259(v=exchg.10).aspx
https://managedesent.codeplex.com/
https://en.wikipedia.org/wiki/Extensible_Storage_Engine
ESENT очень широко используется внутри самой Windows, это нативное win32 API со всеми последствиями, но есть обёртка под .NET и работает это решение даже на WindowsPhone и в UWP приложениях (Даже в плеере Zune в качестве БД использовался ESENT). Потребляет больше памяти чем SQLite, но и больше функционал (снапшот изоляция транзакций, полное журналирование, и т.д.). Из минусов пишут такое: «своеобразные требования к thread-ингу. Приложение может открыть сколько угодно параллельных сессий. Но одна сессия должна жить в рамках одного треда.»
И до 7ки он вроде как был жестко прибит гвоздями к NTFS и зависел от размера кластера, но потом отвязали от NTFS.
https://www.codeproject.com/articles/52715/extensible-storage-engine
https://msdn.microsoft.com/en-us/library/gg269259(v=exchg.10).aspx
https://managedesent.codeplex.com/
https://en.wikipedia.org/wiki/Extensible_Storage_Engine
+2
Спасибо за наводку на LiteDB, пригодится.
+1
В винде же есть shadow copy — реализующий CoW механизмы. Да, вроде как ограничение — снимки распространяются на целый раздел, но выделить отдельный раздел под хранение рабочих файлов, получив взамен все плюшки мгновенных снапшотов состояния и эффективного их хранения, по-моему, должны всё покрывать. И самое главное — это уже есть в самой ОС.
+1
Почитал про эту функцию. Насколько я понимаю, для того чтобы ею воспользоваться файл должен сперва оказаться на диске, верно? Если это так, то нам это не подходит, по причине, что интерес этой фичи представляется именно для несохраненных/измененных файлов. Или я где-то не прав?
0
Да, конечно, файл должен быть на диске.
Но вы хотите сказать, что у вас даже временных файлов нет? Т.е всё всегда в памяти? Задача у вас описана очень туманно. Но обычно IDE всё таки хранят «несохраненные» файлы, чтобы иметь возможность восстановить хотя бы часть работы при падении приложения/ОС.
Но вы хотите сказать, что у вас даже временных файлов нет? Т.е всё всегда в памяти? Задача у вас описана очень туманно. Но обычно IDE всё таки хранят «несохраненные» файлы, чтобы иметь возможность восстановить хотя бы часть работы при падении приложения/ОС.
+1
Еще как вариант LMDB. По максимуму использует оперативку, очень хороши флашит данные на диск. В базе размером 25гб и с количеством записей 300млн поиск выполняется за 1-3мс при условии что SSD на вирт машине.
Единственный минус — должен быть один писатель. Но кроссплатформенный
Единственный минус — должен быть один писатель. Но кроссплатформенный
+1
brightstardb не пробовали? было бы интересно сравнение
+1
Не случилось, но спасибо за наводку. Глану в этом направлении
0
если доберетесь раньше — было бы интересно узнать мнение о бенчмарках и размерах кода в сравнении с LiteDB…
функциональность у b* предлагает больше возможностей на первый взгляд
еще в разное время попадали в поле зрения:
https://ndatabase.codeplex.com/
https://github.com/Wintellect/SterlingDB
оба проекта в затишье похоже
но последний зацепился из за того что был дополнен драйвером к azure tables, а это дешевое хранилище… если актуально конечно
а ndatabase показался довольно проработанным в плане примеров, даже linqpad поддержан. но мне показалось что он не претендент по скоростным возможностям ;((
функциональность у b* предлагает больше возможностей на первый взгляд
еще в разное время попадали в поле зрения:
https://ndatabase.codeplex.com/
https://github.com/Wintellect/SterlingDB
оба проекта в затишье похоже
но последний зацепился из за того что был дополнен драйвером к azure tables, а это дешевое хранилище… если актуально конечно
а ndatabase показался довольно проработанным в плане примеров, даже linqpad поддержан. но мне показалось что он не претендент по скоростным возможностям ;((
0
Sign up to leave a comment.
В поисках быстрого локального хранилища