Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.56 MB
Время: 0.019 c
2-1221658980
smartleds
2008-09-17 17:43
2008.10.26
Господа, напомните пожалуйста функцию задержки в Делфи


2-1221833280
Alexei
2008-09-19 18:08
2008.10.26
Запуск приложения


2-1221795539
031178
2008-09-19 07:38
2008.10.26
Как объеденить 2 таблички в MS SQL


2-1221812490
Alex86
2008-09-19 12:21
2008.10.26
Вложенный запрос


2-1221686355
DBGrid
2008-09-18 01:19
2008.10.26
Убрать ScrollBar