【问题标题】:Hash a temp-table row散列临时表行
【发布时间】:2016-09-10 16:01:23
【问题描述】:

背景故事

我在 Android 客户端的后端工作。要显示的数据很多,需要一些离线功能,所以我必须解决同步问题。所述数据由临时表组成。

我们的解决方案

现在,为了让客户端了解可能的更改,而不是强制执行完整的客户端数据库擦除和创建(需要很多时间),我对每个临时表进行 散列行。所述散列是通过获取临时表行,为其创建一个 JSON,然后从该 JSON 中生成一个散列来创建的。它正在工作。

我对这个解决方案的问题

我认为这不是理想的解决方案。所有这些操作看起来都要求很高,从我的测试中可以看出:

  • 对于每个数据;基线,无操作 = 90 毫秒
  • 在其中填充一个临时表,每个缓冲区复制 = 400 毫秒
  • 在 for each = 2 880 ms 内填充后使用上述解决方案计算哈希

我想要什么

如果我们做错了什么,我很感兴趣。这个问题有更好的解决方案吗?有没有对每个单独的临时表记录创建散列要求不高的方法?

我们目前正在使用 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.

我想要什么

  • 要知道我们是否做错了什么,由于某种原因,这个解决方案在我看来并不正确,我相信有人也必须面对这个问题(创建临时表的哈希)
  • 这确实需要很多时间,并且将来应该是一个问题,所以我想尽快解决这个问题

【问题讨论】:

  • 怎样才能使解决方案“更好”?更短的时间?内存少?更可维护的代码?如果您发布显示当前解决方案的示例代码也会很有帮助。
  • 嗨,汤姆,感谢您的反应。我已按要求更新了问题。更少的时间是我最大的问题。
  • 优秀的文章!

标签: progress-4gl openedge


【解决方案1】:

这是一个快近 20 倍的哈希解决方案(对于 1000 次调用,它是 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-TRANSFER 方法仅适用于缓冲区字段对象句柄,因此在 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 方法的版本更快。

【讨论】:

  • 这看起来很棒!当我有时间时,我会尝试实施和测试。
【解决方案2】:

(代表 OP 发布)。

解决方案

我实施了 Mike 建议的解决方案。对于我们的结构,我无法按照建议将帮助内容移动到程序之外。在实现我的现实世界问题并测量整个过程的时间后,通过 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)).

我们遇到的问题

我们终于有时间根据 Mike 的建议进一步优化它(临时表定义和创建只调用一次),现在速度更快了。我真的不明白为什么临时表定义,但主要是创建记录,是“慢”的。

还请记住,raw-transfer 方法不能用于大于 32kB 的字段。

【讨论】:

    猜你喜欢
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    相关资源
    最近更新 更多