用串联运算符&&或字符串模板|…|:
DO | WHILE | LOOP | SELECT…
str=str&&…
str=|{str}…|。
ENDDO | END | ENDWHILE | ENDSELECT…
这两种赋值都有一个字符串表达式作为RHS(右手)侧面)。那是什么意思?通常,在分配表达式时,会创建一个临时或中间结果,该结果必须复制到LHS(左侧)。由于中间结果的长度随着每个循环过程而增加,并且每个循环过程都有一个复制操作,因此循环过程数的运行时依赖性是二次的。不好。
因为这是众所周知的事实,所以所有的连接都有一个内部优化,如下所示:
str=str&&dobj1&&dobj2&&….
str={str}…{dobj1[格式选项]}…{dobj2[格式选项]}…|。
只要
没有创建中间结果,但是直接连接字符这可以防止运行时的二次依赖关系影响迭代次数。连接语句也是如此。
换言之,德国云服务器,写这样的东西没有问题:
DATA(html)=``.
DO…次。
html={html}{sy index}
}.
ENDDO.
html=html&&``.
有一个简单的数据对象sy index连接到目标字符串html,并进行优化。
优化只发生在上述简单的情况下!
这就是陷阱
你失去了优化,如果循环如下所示的连接:
str=str&&…&&&meth(…)&&…
str=str&&…&&str&&…
str=|{str}…{expr(…)}…|。
str=|{str format_options}…|。
str str=|{str str}…{str}…|。
只要在循环外执行这种连接,就没有问题。但是在循环内部和大量的迭代中,你可以很快体验到非常大的运行时,写一些看起来像这样无害的东西:
DATA(html)=``.
DO…次。
html={html}{
CONV string(ipow(base=sy index exp=2))
}
|。
ENDDO.
html=html&&``.
将ipow表达式连接到str打破了优化。
现在你知道这个问题,你可以很容易地绕过它。通常我们使用表达式来摆脱助手变量。但是在循环中,辅助变量是一件好事。您已经知道使用它们来计算循环中恒定的结果。现在您了解到,消防物联网,还应该使用它们将表达式或函数连接到字符串:
DATA(html)=``.
DATA square type string.
DO。。。TIMES.
square=ipow(base=sy–index exp=2)。
html={html}{square}
|。
ENDDO.
html=html&&``。
通过将ipow表达式分配给助手变量square并将其连接到str,优化再次发生。你自己试试看,看看有优化和没有优化的大量迭代会发生什么!
最后但并非最不重要的是,上面所说的由控制语句实现的循环对于表达式中的循环也是如此:
DATA(result)=
REDUCE string(INIT s="
for i=1 UNTIL i>。
NEXT s=s&&CONV string(i))。
vs.
DATA(result)=
REDUCE string(INIT s="
for i=1 UNTIL i>。
LET num=CONV string(i))在
NEXT s=s&&num).
中,只有使用LET表达式中声明的辅助变量num,十大淘客软件排名,才能启用优化。没有helper变量的例子显示了运行时间随迭代次数的二次增加。
最后一个例子直接取自最近的文档。但你知道吗?
超级内容霍斯特!谢谢你强调这个陷阱。
不是在我最疯狂的梦里。在我们的ABAP740(SP12)系统上,它的性能提高了近500
嗨,霍斯特,
谢谢你的帖子。很高兴知道。我不希望字符串串联中出现任何性能陷阱。对我来说,这打破了惯例(https://de.wikipedia.org/wiki/Principle\u of \u Least\u)
然而,我想知道为什么ABAP运行时不能处理这些情况
我天真的假设是,自动执行由附加变量引入的优化应该非常容易。
Christian
是的,很遗憾。我写了这个博客,尽管它会给人留下不好的印象。但是最好知道缺陷而不是隐藏它们…
有没有什么特殊的原因,内部优化不能处理与变量相同的表达式?
另一种情况:当目标字符串str只在RHS出现一次并且作为最右边的运算符出现时?
所有可能依赖LHS的东西在使用前都会得到一份LHS。ABAP不检查表达式。
只在str的右端连接。str列在最左边。
我在SAP 750/003上。
在我的系统中尝试这个性能陷阱时,购物返现网,我想知道从AMDP获取数据并在DB级别连接是否会有任何性能改进。但看到结果我很震惊。
这是SAT截图。
下面是程序:
报告ztest\u sm。
参数:p\u vbeln TYPE vbeln\u va。
类型:
tyu salesord开始,
vbeln TYPE vbeln\u va,
posnr TYPE posnr\u va,
matnr TYPE matnr,
tyu salesord结束,
TTU salesord类型ty\u salesord标准表
数据:
lv\u oldstr类型字符串,
lv\u newstr类型字符串,
lv\u finstr类型字符串,
lv\u matnr类型字符串,物联网产品,
li\u数据类型tt\u salesord.
开始选择。
执行f\u get\u data CHANGING li\u data.
使用li\u data执行f\u old\u concat.
使用li\u data执行f\u new\u concat.
使用li\u data执行f\u imp\u concat.
使用li\u data执行f\u amd\u concat.
*&--------------------------------------------------------------------
*&FormF\ GET\ U DATA
*&--------------------------------------------------------------------------*
*text
*-----------------------------------------------------------------*
*P|u LO|u DREF text
*------------------------------------------------------------------------------
使用fp|u li|u数据类型tt|salesord形成f|old|concat.
写入:/|常规连接|。
将fp|u li|u数据循环到数据中(lw|salesord)。
将lv|u oldstr
lw|salesord-matnr
连接到lv|u oldstr中,用分隔空格
结束循环
写入:/lv\u oldstr.
结束形式
*&----------------------------------------------------------*
*&新形式
*&-----------------------------------------------------*
*文本
*--------------------------------------------------------------------
*-->PаLIаu数据文本
*--------------------------------------------------------------------
使用fpаLIаu数据类型ttаsalesord形成新的аconcat.
写入:/|新的串联|。
将fpаLIаu数据循环到数据中(lwаu salesordаn.
lv U newstr=lv|U newstr&&
|&&
lw|U salesord
n-matnr.
ENDLOOP.
WRITE:/lv|U newstr.
ENDFORM.
*&--------------------------------------------------------------------
*&Form F|U IMP|U CONCAT
*&--------------------------------------------------------------------*
文本
*-----------------------------------------------------------------*
*-->PèLIè数据文本
*-----------------------------------------------------------------*
使用fpèLIè数据类型ttèsalesord形成fèimpèconcat.
写入:/|微调串联|。
将fpèLIè数据循环到数据(lw|u salesord|f.
lv|matnr=lw|u salesord|f-matnr.
lv|finstr=lv|finstr&&
lv|matnr.
ENDLOOP.
WRITE:/lv|finstr.
ENDFORM.
*&------------------------------------------------------------------------------*
*&FormF\ U AMD\ u CONCAT
*&------------------------------------------------------------------------------*
*text
*--------------------------------------------------------------------*
*
-->P\ u LI\ u DATA text
*---------------------------------------------------------------*
使用fp\ u LI\ u数据类型的表格F\ u AMD\ u CONCATtt|salesord.
WRITE:/| AMDP concatenation |。
NEW zcl|u collect|AMDP()->meth|concat|material(
EXPORTING
im|mandt=sy mandt
im|vbeln=p|vbeln
IMPORTING
et|string=DATA(li|concat)
。
DATA(lv amdstr)=VALUE string(li|concat[1]-str可选)。
WRITE:/lv amdstr
ENDFORM
这是AMDP.
我仍然是一个新手,不太了解AMDP的复杂性。
谢谢!
PS:很抱歉,因为我不知道如何在SCN上粘贴带有ABAP字体的程序。
嗨,Aasim,
霍斯特
谢谢您的输入!
我将很快打开一个关于这个主题的线程
因为您非常活跃…
使用GET RUN TIME字段测量DO循环中的每个访问,并计算平均或最小运行时间。我仍然不敢相信AMDP的坏结果。
霍斯特
嗨霍斯特,
对延误表示歉意;我的交付物有点耽搁了。我按照你的建议做了,并打开了一个线程以供进一步研究讨论。慢点在AMDP的表现
谢谢!
干得好,霍斯特。总是很投入