-
Здравствуйте !
Если кому интересно...
Случайно столкнулась с тем, что на запись некого значения в реестр
уходит гораздо больше времени, чем на чтение этого же параметра.
(В тестах на моем компьютере речь идет о порядках. От одного до двух.
Зависит от способа чтения. На мой взгляд, это неприлично много :)).
По этому поводу решила провести проверку: не выгодно ли иногда
перед записью проверять а нужна ли она (значения совпадают значит нет) ?
Попробуем потестировать на следующей ф-ии: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.
Для тех, кто спросит "а нафига эта ловля блох ?", скажу, что это может понадобиться,
например, при частом сохранении множества настроек (зависит от способа).
Да и просто приятно когда у тебя используются чуть оптимальнее алгоритмы чем раньше :) -
> Результаты: 13987 против 203 тиков.
Ой, соврала. Читать так: Результаты: 13987 против 998 тиков.
(Не из той графы взяла данные) Sorry. -
{RASkov} © (31.08.08 11:41) [2]Ой, Сашка.... твой код все время "страшный", выглядит пугающе... :)
А если тоже самое сделать стандартными(VCL) способами, какие будут результаты?)
Но кстати, нужно будет еще раз проверить, так как я изначально тоже склонялся к тому, чтобы проверять нужна ли запись значения, но потом подумал, что лишние затраты и не стал так делать(т.е. пишу не зависимо от нужды)... С другой стороны, не всегда в этом месте нужна скорость работы программы... я ПыСы прочитал) -
Dmitry S © (31.08.08 12:02) [3]После подобных оптимизаций потом приходится Сплэшскрин удерживать sleep-ом =)
-
Loginov Dmitry © (31.08.08 12:20) [4]> Случайно столкнулась с тем, что на запись некого значения
> в реестр
> уходит гораздо больше времени, чем на чтение этого же параметра.
запись в базу выполняется дольше чтения, это нормально. Реестр - таже база. Тест конечно интересный, заставляет задуматься, что еще такого можно пооптимизировать ;) -
> [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 (31.08.08 16:30) [6]
> Это что серьезно ? Ну тогда я еще и с базами умею работать.
> Во уж чего не ожидала :)
Я удивлен что вы удивлены этому. Реестр - база данных Windows, об этом даже в школе говорят кажись.. -
> [6] Tricky (31.08.08 16:30)
> Я удивлен что вы удивлены этому. Реестр - база данных Windows, об этом даже в школе говорят кажись..
Чес. слово - не знала. Век живи - век учись :) -
ketmar © (31.08.08 16:45) [8]мда. permature optimization… и далее по тексту.
---
Do what thou wilt shall be the whole of the Law. -
ketmar © (31.08.08 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 © (31.08.08 17:40) [10]нафиг этот реестр
не люблю когда программа не удаляет после себя всё что оставила в реестре (а ставлю "на посмотреть" различный софт я часто) -
asail (31.08.08 18:27) [11]
> VirEx © (31.08.08 17:40) [10]
> нафиг этот реестр
> не люблю когда программа не удаляет после себя всё что оставила
> в реестре (а ставлю "на посмотреть" различный софт я часто)
А реестр тут причем? Все притензии к разработчикам конкретного софта и инсталяторов. -
VirEx © (31.08.08 20:09) [12]
> [11] asail (31.08.08 18:27)
>
> А реестр тут причем? Все притензии к разработчикам конкретного
> софта и инсталяторов.
ну собственно не выразил всё что хотел сказать: в последнее время считаю что лучше portable версия программы чем инсталлирующаяся в систему по самые помидоры, изза чего ОСь начинает глючить
пусть свои настройки хранят в своей базе, например в sqlite формате -
antonn © (31.08.08 20:20) [13]в ini-файле :)
-
Городской Шаман (01.09.08 04:42) [14]
> antonn © (31.08.08 20:20) [13]
>
> в ini-файле :)
В xml. -
turbouser © (01.09.08 05:05) [15]
> Городской Шаман (01.09.08 04:42) [14]
>
>
> > antonn © (31.08.08 20:20) [13]
> >
> > в ini-файле :)
>
>
> В xml.
Счас! ini наше всё :) -
brother © (01.09.08 05:09) [16]> в ini-файле :)
+1
зы спорили уже по этому поводу ;) -
Джо © (01.09.08 07:18) [17]
> brother © (01.09.08 05:09) [16]
> +1 зы спорили уже по этому поводу ;)
... неоднократно.
Вывод таков — каждый овощ... и так далее :)