Текущий архив: 2008.10.26;
Скачать: CL | DM;
Вниз
Запись и чтение реестра. Найти похожие ветки
← →
Riply © (2008-08-31 10:38) [0]Здравствуйте !
Если кому интересно...
Случайно столкнулась с тем, что на запись некого значения в реестр
уходит гораздо больше времени, чем на чтение этого же параметра.
(В тестах на моем компьютере речь идет о порядках. От одного до двух.
Зависит от способа чтения. На мой взгляд, это неприлично много :)).
По этому поводу решила провести проверку: не выгодно ли иногда
перед записью проверять а нужна ли она (значения совпадают значит нет) ?
Попробуем потестировать на следующей ф-ии:function NtVerifySetValueKey(const KeyHandle: THANDLE; const uValueName: PUNICODE_STRING;
const TitleIndex, aValueType: ULONG; pValueData: PVOID; ValueDataLength: ULONG): NTSTATUS;
var
pValueInfo: PKEY_VALUE_PARTIAL_INFORMATION;
ValueInfoSize, BytesReturn: ULONG;
begin
ValueInfoSize := SizeOf(_KEY_VALUE_PARTIAL_INFORMATION) - SizeOf(Char) + ValueDataLength;
pValueInfo := GetMemory(ValueInfoSize);
try
Result := NtQueryValueKey(KeyHandle, uValueName, KeyValuePartialInformation, pValueInfo, ValueInfoSize, @BytesReturn);
if NT_SUCCESS(Result) then
with pValueInfo^ do
if (ValueType = aValueType) and (DataLength = ValueDataLength)
and CompareMem(pValueData, @Data, DataLength) then Exit;
Result := NtSetValueKey(KeyHandle, uValueName, TitleIndex, aValueType, pValueData, ValueDataLength);
finally
FreeMemory(pValueInfo);
end;
end;
Примечания к NtVerifySetValueKey:
1. Вычисление значение ValueInfoSize зависит от того как определена структура _KEY_VALUE_PARTIAL_INFORMATION
(например она packed или нет)
Цель точного определения этого размера в попытке получить STATUS_BUFFER_OVERFLOW, STATUS_BUFFER_TOO_SMALL
как результат вызова NtQueryValueKey, если размер данных в реестре хоть на байт больше ValueDataLength.
Во-первых в этом случае гораздо быстрее отрабатывает сама NtQueryValueKey
Во-вторых, нам не надо проводить дальнейшую проверку, а мы ведь ленивые :)
2. NtVerifySetValueKey специально написана довольно неоптимальным образом.
(например, если aValueType = REG_QWORD или REG_DWORD, то нам совсем не нужно
выделять, освобождать память, да еще и сравнивать два DWORD`а через CompareMem:)
есть еще несколько моментов, которые можно учесть. Оставляю это заинтересованным лицам :))
А мы будем тестировать на неоптимальном варианте, что бы уж если будет положительный результат,
то с большим запасом :)
Для теста, я создала десять значений, одно из которых имеет тип REG_BINARY, одно REG_SZ,
остальные - REG_QWORD и REG_DWORD.
Далее в цикле от 0 до 10000 прогнала NtSetValueKey и NtVerifySetValueKey.
Результаты: 13987 против 203 тиков.
Довольно неплохо, особенно если учесть неоптимальность NtVerifySetValueKey :).
И под конец добавлю, когда речь идет о многих значениях одного ключа,
вместо NtQueryValueKey, лучше использовать NtEnumerateValueKey (или NtQueryMultipleValueKey).
Это даст нам еще одну (кстати довольно существенную) прибавку в скорости.
Уфф. пока, вроде все.
P.S.
Для тех, кто спросит "а нафига эта ловля блох ?", скажу, что это может понадобиться,
например, при частом сохранении множества настроек (зависит от способа).
Да и просто приятно когда у тебя используются чуть оптимальнее алгоритмы чем раньше :)
← →
Riply © (2008-08-31 11:00) [1]> Результаты: 13987 против 203 тиков.
Ой, соврала. Читать так: Результаты: 13987 против 998 тиков.
(Не из той графы взяла данные) Sorry.
← →
{RASkov} © (2008-08-31 11:41) [2]Ой, Сашка.... твой код все время "страшный", выглядит пугающе... :)
А если тоже самое сделать стандартными(VCL) способами, какие будут результаты?)
Но кстати, нужно будет еще раз проверить, так как я изначально тоже склонялся к тому, чтобы проверять нужна ли запись значения, но потом подумал, что лишние затраты и не стал так делать(т.е. пишу не зависимо от нужды)... С другой стороны, не всегда в этом месте нужна скорость работы программы... я ПыСы прочитал)
← →
Dmitry S © (2008-08-31 12:02) [3]После подобных оптимизаций потом приходится Сплэшскрин удерживать sleep-ом =)
← →
Loginov Dmitry © (2008-08-31 12:20) [4]> Случайно столкнулась с тем, что на запись некого значения
> в реестр
> уходит гораздо больше времени, чем на чтение этого же параметра.
запись в базу выполняется дольше чтения, это нормально. Реестр - таже база. Тест конечно интересный, заставляет задуматься, что еще такого можно пооптимизировать ;)
← →
Riply © (2008-08-31 16:13) [5]> [2] {RASkov} © (31.08.08 11:41)
> А если тоже самое сделать стандартными(VCL) способами, какие будут результаты?)
Ой не хочу возится с TRegistry. Ну не нравится он мне очень.
Так не нравится, что даже определение "некузявый" для него слишком хорошее :)
Зато попробовала заменить NtQueryValueKey на NtEnumerateValueKey.
Правда, внуть тестового цикла пришлось еще запихать сортировку и бинарный поиск.
Но даже с этими прибамбасами, скорость повысилась еще в 4 раза.
На этом, наверное и остановимся :)
> [3] Dmitry S © (31.08.08 12:02)
> После подобных оптимизаций потом приходится Сплэшскрин удерживать sleep-ом =)
:)
У каждого свои проблеммы :)
> [4] Loginov Dmitry © (31.08.08 12:20)
> запись в базу выполняется дольше чтения, это нормально. Реестр - таже база.
Это что серьезно ? Ну тогда я еще и с базами умею работать. Во уж чего не ожидала :)
← →
Tricky (2008-08-31 16:30) [6]
> Это что серьезно ? Ну тогда я еще и с базами умею работать.
> Во уж чего не ожидала :)
Я удивлен что вы удивлены этому. Реестр - база данных Windows, об этом даже в школе говорят кажись..
← →
Riply © (2008-08-31 16:39) [7]> [6] Tricky (31.08.08 16:30)
> Я удивлен что вы удивлены этому. Реестр - база данных Windows, об этом даже в школе говорят кажись..
Чес. слово - не знала. Век живи - век учись :)
← →
ketmar © (2008-08-31 16:45) [8]мда. permature optimization… и далее по тексту.
---
Do what thou wilt shall be the whole of the Law.
← →
ketmar © (2008-08-31 16:46) [9]>[7] Riply © (2008-08-31 16:39:00)
дык это… ты не поверишь. .ini-файл — это тоже база данных. и CSV — тоже база. любая фиготень, где хранятся какие-то данные, которые можно программно добывать хотя бы — это база данных.
---
Do what thou wilt shall be the whole of the Law.
← →
VirEx © (2008-08-31 17:40) [10]нафиг этот реестр
не люблю когда программа не удаляет после себя всё что оставила в реестре (а ставлю "на посмотреть" различный софт я часто)
← →
asail (2008-08-31 18:27) [11]
> VirEx © (31.08.08 17:40) [10]
> нафиг этот реестр
> не люблю когда программа не удаляет после себя всё что оставила
> в реестре (а ставлю "на посмотреть" различный софт я часто)
А реестр тут причем? Все притензии к разработчикам конкретного софта и инсталяторов.
← →
VirEx © (2008-08-31 20:09) [12]
> [11] asail (31.08.08 18:27)
>
> А реестр тут причем? Все притензии к разработчикам конкретного
> софта и инсталяторов.
ну собственно не выразил всё что хотел сказать: в последнее время считаю что лучше portable версия программы чем инсталлирующаяся в систему по самые помидоры, изза чего ОСь начинает глючить
пусть свои настройки хранят в своей базе, например в sqlite формате
← →
antonn © (2008-08-31 20:20) [13]в ini-файле :)
← →
Городской Шаман (2008-09-01 04:42) [14]
> antonn © (31.08.08 20:20) [13]
>
> в ini-файле :)
В xml.
← →
turbouser © (2008-09-01 05:05) [15]
> Городской Шаман (01.09.08 04:42) [14]
>
>
> > antonn © (31.08.08 20:20) [13]
> >
> > в ini-файле :)
>
>
> В xml.
Счас! ini наше всё :)
← →
brother © (2008-09-01 05:09) [16]> в ini-файле :)
+1
зы спорили уже по этому поводу ;)
← →
Джо © (2008-09-01 07:18) [17]
> brother © (01.09.08 05:09) [16]
> +1 зы спорили уже по этому поводу ;)
... неоднократно.
Вывод таков — каждый овощ... и так далее :)
← →
Игорь Шевченко © (2008-09-01 13:40) [18]эта...все понимаю, как собака Павлова, сказать только не могу. Но один вопрос таки имеется - а нафига, собственно, обращать внимание на время записи в реестр ? Да и на время чтения тоже...
← →
clickmaker © (2008-09-01 13:42) [19]в ini, кстати, долго пишется. Если настроек много
← →
Игорь Шевченко © (2008-09-01 13:55) [20]
> в ini, кстати, долго пишется. Если настроек много
да, долго. Могу даже сказать, почему - каждый write в ini выполняется отдельной операцией записи, то есть, если сначала сохранить нужное в памяти, а потом одним махом записать cодержимое всего файла, то скорость повысится на порядки
← →
Riply © (2008-09-01 14:01) [21]> [18] Игорь Шевченко © (01.09.08 13:40)
> Но один вопрос таки имеется - а нафига, собственно, обращать внимание
> на время записи в реестр ? Да и на время чтения тоже...
Да случайно получилось. Стало подтормаживать приложение при загрузке/выгрузке.
Решила посмотреть куда время уходит. Разбила на блоки (их у меня много разных)
и засекла время для каждого из них.
Вот тут-то и увидела, что сохранение настроек занимает
аж на два порядка больше времени чем их чтение.
Очень удивилась и решила посмотреть "а почему" :)
← →
clickmaker © (2008-09-01 14:04) [22]> если сначала сохранить нужное в памяти, а потом одним махом
> записать cодержимое всего файла, то скорость повысится на
> порядки
ага. Типа TMemIniFile
← →
blackman © (2008-09-01 14:05) [23]Игорь Шевченко © (01.09.08 13:55) [20]
...если сначала сохранить нужное в памяти, а потом одним махом записать cодержимое всего файла, то скорость повысится на порядки
Т.е. от write ini отказаться и писать файл самому? Или как?
← →
Игорь Шевченко © (2008-09-01 14:17) [24]blackman © (01.09.08 14:05) [23]
> Т.е. от write ini отказаться и писать файл самому? Или как?
Можно использовать TMemIniFile из inifiles.pas
← →
blackman © (2008-09-01 14:29) [25]ini.UpdateFile; понял.
Только при большом файле память будет жрать и все в своп полезет, что не есть хорошо.
← →
clickmaker © (2008-09-01 14:33) [26]> Только при большом файле память будет жрать и все в своп
> полезет,
это ж сколько настроек должно быть?
у меня WritePrivateProfileString тормозить начинало уже при 20К где-то... пришлось свой класс писать для записи ини
← →
Игорь Шевченко © (2008-09-01 14:41) [27]
> Только при большом файле память будет жрать и все в своп
> полезет
Насколько большом ?
← →
Eraser © (2008-09-01 14:48) [28]> [25] blackman © (01.09.08 14:29)
у обычного ини-файла жесткое ограничение на размер. именно поэтому эту устаревшую технологию надо забывать )
← →
blackman © (2008-09-01 15:21) [29]Я INI стараюсь не пользоваться. Все настройки обычно в БД.
← →
Loginov Dmitry © (2008-09-01 20:43) [30]> у меня WritePrivateProfileString тормозить начинало уже
> при 20К где-то... пришлось свой класс писать для записи
> ини
это не предел. Вот в нашей системе бОльшая часть конфигурационных параметров хранится в одной инишке, она до 60К доходит, иногда и больше. В принципе практически не тормозит. Однако у некоторых клиентов работа системы изредка зверски тормозила (можно сказать "зависала"), было пару раз, даже конфигурация слетала. При детальном разборе оказалось, что у всех у них стоит Nod32. А слетала конфигурация по простой причине: с помощью EraseSection удалялась секция (в ней порядка 300 значений), после чего обновленные значения вновь записывались в эту секцию. Антивирус после записи каждого значения проверял файл на вирусы, в результате эти 300 значений записывались порядка минуты. Операторы не дожидались окончания записи (думали что все повисло) и тупо ресетили комп.
← →
Loginov Dmitry © (2008-09-01 20:46) [31]> у обычного ини-файла жесткое ограничение на размер. именно
> поэтому эту устаревшую технологию надо забывать )
там сейчас нет никаких ограничений. В Win98 было ограничение - 65535К максимум (строковае значение без учета имени параметра). В WinXP максимальный размер строки 65535К, а размер файла - не ограничен. Естественно для больших файлов скорость чтения/записи заметно падает.
← →
Loginov Dmitry © (2008-09-01 20:52) [32]> ага. Типа TMemIniFile
кстати да, скорость высокая, мегабайты в тестах молотит тока ну. Еще плюсы: не чувствительна к русским символам, длина строки не ограничена. Минусы - только для монопользого использования, автоматически не обрубает кавычки.
Страницы: 1 вся ветка
Текущий архив: 2008.10.26;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.005 c