Конференция "Прочее" » Запись и чтение реестра.
 
  • Riply © (31.08.08 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 © (31.08.08 11:00) [1]
    > Результаты: 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]
    > Случайно столкнулась с тем, что на запись некого значения
    > в реестр
    > уходит гораздо больше времени, чем на чтение этого же параметра.


    запись в базу выполняется дольше чтения, это нормально. Реестр - таже база. Тест конечно интересный, заставляет задуматься, что еще такого можно пооптимизировать ;)
  • Riply © (31.08.08 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 (31.08.08 16:30) [6]

    > Это что серьезно ? Ну тогда я еще и с базами умею работать.
    >  Во уж чего не ожидала :)


    Я удивлен что вы удивлены этому. Реестр - база данных Windows, об этом даже в школе говорят кажись..
  • Riply © (31.08.08 16:39) [7]
    > [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 зы спорили уже по этому поводу ;)

    ... неоднократно.
    Вывод таков — каждый овощ... и так далее :)
 
Конференция "Прочее" » Запись и чтение реестра.
Есть новые Нет новых   [134442   +10][b:0][p:0.001]