2016-07-14 7 views
2

BackstoryHash ТЕмп-строка таблицы

Я работаю на серверной для Android клиентов. Есть много данных, которые нужно отобразить, и некоторые автономные функции нужны, поэтому мне приходится решать синхронизацию. Указанные данные состоят из временных таблиц.

Наше решение

Прямо сейчас, чтобы позволить клиенту знать о возможных изменениях, а не для обеспечения полного клиента БД протирать и создание (занимает много времени), я делаю хэш каждого из строки temp-table. Указанный хеш создается, беря строку temp-table, создавая для нее JSON, а затем создавая хэш из этого JSON. Это работает.

Мои проблемы с этим раствором

Я думаю, что это не идеальное решение. Все эти операции выглядят сложными и из моих испытаний показывают:

  • Для каждого из данных; базовая линия, никаких действий = 90 мс
  • населения той или иной темп-таблицы внутри, что для каждой из буферной копии = 400 мс
  • Вычисление хэш с указанным выше раствором после населения внутри для каждого = 2 880 мс

То, что я хочу

Я интересно, если мы делаем что-то неправильно. Есть ли лучшее решение для этой проблемы? Существует ли менее сложный способ создания хэша из каждой отдельной записи временного стола?

В настоящее время мы используем OpenEdge 10.2B.

Процедура отвечает за создание хэш, create_hash создать виджет-бассейн.

define input parameter inp_hBuffer as handle no-undo. 
define output parameter out_cHash as c no-undo. 

define var ttDynamic as handle no-undo. 
define var hBufferTT as handle no-undo. 

define var lResult as l no-undo. 
define var cDataTT as longchar no-undo. 

define var itime as i. 

do on error undo,return error: 
    if not(valid-handle(inp_hBuffer) and inp_hBuffer:type = 'BUFFER':u) then 
     return error substitute('Neplatny typ vstupniho parametru predaneho procedure "&1".','m_ghashb':u). 

    create temp-table ttDynamic. 
    ttDynamic:add-fields-from(inp_hBuffer). 
    ttDynamic:temp-table-prepare(inp_hBuffer:table). 

    hBufferTT = ttDynamic:default-buffer-handle. 

    hBufferTT:buffer-copy(inp_hBuffer). 
    ttDynamic:write-json('longchar':u,cDataTT). 

    out_cHash = hex-encode(md5-digest(cDataTT)). 
end. 

return. 

И его использование

for first lbUsrtab where 
    lbUsrtab.ucje = GetUcje('m_usrtab':U) and 
    lbUsrtab.login-name = LoginName no-lock, 
each lbWcesta where 
    lbWcesta.ucje = GetUcje('wcesta':U) and 
    lbWcesta.kodu = lbUsrtab.kodu no-lock, 
each lbWciorg where 
    lbWciorg.ucje = GetUcje('wciorg':U) and 
    lbWciorg.cest = lbWcesta.cest no-lock, 
each lbKontaktr where 
    lbKontaktr.ucje = GetUcje('kontaktr':U) and 
    lbKontaktr.corg = lbWciorg.corg no-lock 
    by lbKontaktr.zako descending 
    on error undo, return error return-value: 

    create ttKontaktr. 
    buffer-copy lbKontaktr to ttKontaktr. 
    run create_hash(input buffer ttKontaktr:handle, output ttKontaktr.hash). 
end. 

Я хочу

  • знать, если мы делаем что-то неправильно, это решение не смотреть прямо на меня по какой-то причине и я уверен, что кому-то пришлось столкнуться с этим тоже (создание хэша временного стола)
  • это займет много времени и должно быть проблемой в будущем, поэтому я хотел бы подойти к этому раньше, чем позже
+0

Что сделало бы решение «лучше»? Меньше времени? Меньше памяти? Более удобный код? Было бы также полезно, если бы вы разместили образец кода, показывающий ваше текущее решение. –

+0

Привет, Том, спасибо за реакцию. Я обновил вопрос по запросу. Меньше времени для меня самая большая проблема. –

+0

Отличная рецензия! –

ответ

4

Это почти в 20 раз быстрее, решение вашей хэш (для 1000 invokations это 320 мс против 17 мса):

PROCEDURE hash2: 
    DEFINE INPUT PARAMETER inp_hBuffer AS HANDLE NO-UNDO . 
    DEFINE OUTPUT PARAMETER out_cHash AS CHARACTER NO-UNDO . 

    inp_hBuffer:RAW-TRANSFER (TRUE, hRawField) . 

    out_cHash = HEX-ENCODE (MD5-DIGEST (ttWithRaw.raw_field)). 
END PROCEDURE . 

Вам нужен помощник ТЕМП-таблица с RAW полем и одной записью, так как метод RAW-ПЕРЕДАЧА в буферном дескрипторе объекта работает только на предметной ручке буфера поля , так что что-то вроде этого вне процедуры hash2, вам нужно запустить его только один раз:

DEFINE VARIABLE hRawField AS HANDLE NO-UNDO. 

DEFINE TEMP-TABLE ttWithRaw NO-UNDO 
    FIELD raw_field AS RAW . 

ASSIGN hRawField = BUFFER ttWithRaw:BUFFER-FIELD("raw_field") . 

CREATE ttWithRaw . 

Я еще не пробовал оптимизировать ваш код.

Мне интересно, если мы делаем что-то неправильно. Есть ли лучшее решение для этой проблемы? Существует ли менее сложный способ создания хэша из каждой отдельной записи временного стола?

Хорошая часть времени выполнения будет заключаться в создании динамической временной таблицы для каждой записи - и я сомневаюсь, что вам понадобится создать эту временную таблицу для каждой записи снова и снова.

Может быть, перемещая эту часть

create temp-table ttDynamic. 
    ttDynamic:add-fields-from(inp_hBuffer). 
    ttDynamic:temp-table-prepare(inp_hBuffer:table). 

из процедуры хеширования, ваш код улучшится, а также. Однако я сомневаюсь, что он будет быстрее, чем версия, основанная на методе RAW-TRANSFER.

+0

Это выглядит великолепно! Я попытаюсь реализовать и проверить, когда у меня есть время. –

0

(Отправлено от имени ОП).

Решение

Я реализовал решение, предложенное Майком. Для нашей структуры я не могу перемещать содержимое помощника вне процедуры, как было предложено. После реализации моей реальной задачи и измерения времени всего процесса, с 2450 вызовами, я получаю 2054 мс для предыдущего решения, в отличие от решений Майка, которые занимают всего 240 мс. Это означает, что я не могу реализовать реальный мир, чтобы получить полную выгоду, но даже в 8,5 раза быстрее работает для меня очень хорошо. Я буду помнить все это и вернуться к нему, чтобы еще больше оптимизировать, когда у меня есть время.

Вот как моя процедура выглядит

DEFINE INPUT PARAMETER inp_hBuffer AS HANDLE NO-UNDO . 
DEFINE OUTPUT PARAMETER out_cHash AS CHARACTER NO-UNDO . 

DEFINE VARIABLE hRawField AS HANDLE NO-UNDO. 
DEFINE TEMP-TABLE ttWithRaw NO-UNDO 
    FIELD raw_field AS RAW . 

ASSIGN hRawField = BUFFER ttWithRaw:BUFFER-FIELD("raw_field") . 
CREATE ttWithRaw . 

inp_hBuffer:RAW-TRANSFER (TRUE, hRawField) . 
out_cHash = HEX-ENCODE (MD5-DIGEST (ttWithRaw.raw_field)). 

Проблемы с которыми мы столкнулись

Мы, наконец, получили время для дальнейшей оптимизации его в соответствии с предложением Майка (определение температуры стола и создания вызываются только один раз) и теперь он еще быстрее. Я действительно не понимаю, почему определение временной таблицы, но в основном создание записи, является «медленным».

Также имейте в виду, что метод raw-transfer не может работать с полями размером более 32 КБ.

 Смежные вопросы

  • Нет связанных вопросов^_^