zoukankan      html  css  js  c++  java
  • 读取SAP CRM One Order应用日志的优化方式

    Recently I am responsible for the performance optimization of one API which retrieves application logs of the given one order documents.

    API Requirement

    The input is an internal table containing document guids, and output are all the application logs belonging to those documents, with type “Error” and priority “Very important” and “Important”.

    For the application logs of a single document, you can view them via tcode SLG1 as below:


    The application logs would be displayed in WebUI as below:

    The signature of API:

    The structure of table type CRMT_ODATA_TASK_LOGST could be found below:

    Original implementation ( has performance issue )

    The idea of original implementation is:

    LOOP AT it_order_guid_tab.
            " get all of the message handles of the current order by its guid and stores to variable lt_message_handles
            LOOP AT lt_message_handles.
                  " get the detail of each message according to its handle
            ENDLOOP.
    ENDLOOP.
    

    As you see there are nested loop, so the algorithm complexity is o(n2).

    The optimized implementation

    The idea is to avoid the nested LOOP.

    " get all message handles belonging to all orders in a single method call
    lt_all_message_handlers = get_all( it_order_guid_tab ).
    LOOP AT lt_all_message_handlers.
           " get the detail of each message according to its handle
    ENDLOOP.
    

    The algorithm complexity is reduced to o(n).
    The original implementation could be found from method GET_ORDER_ERROR_MESSAGE of the class CL_CRM_ORDER_MESSAGE_TOOL in the attachment. The optimized version is in method GET_ORDER_ERROR_MESSAGE_OPT.

    Performance comparison

    I do the performance measurement based on the following three scenarios. We can see the performance is improved a lot after nested LOOP is removed.

    The idea of original implementation is:

    Unit Test

    In order to guarantee that the optimized implementation does return exactly the same data as the original one, I write the following report to do unit test. The design is quite simple, retrieve the application log for the same input twice, one using the original implementation and the other one using the optimized version, and eASSERT lt_result1 = lt_result2.
    The report source code is attached here:

    REPORT tool_display_log_compare.
    CLASS lcl_test DEFINITION.
      PUBLIC SECTION.
        METHODS: test_all_oppt, test_created_by_jerry, test_oppt_jerry,
          constructor.
      PRIVATE SECTION.
        METHODS:       get_oppt_guid, compare, get_created_by, get_oppt_jerry.
        DATA: mt_guid_tab   TYPE crmt_object_guid_tab,
              mt_msg_origin TYPE crmt_odata_task_logst,
              mt_msg_opt    LIKE mt_msg_origin,
              mo_tool       TYPE REF TO cl_crm_order_message_tool.
    ENDCLASS.
    CLASS lcl_test IMPLEMENTATION.
      METHOD: test_oppt_jerry.
         get_oppt_jerry( ).
         compare( ).
         WRITE: / 'lines of message: ' , lines( mt_msg_origin ).
         WRITE: / 'test on all Opportunity with type OPPT and created by Jerry passed.' COLOR COL_NEGATIVE.
      ENDMETHOD.
      METHOD: test_created_by_jerry.
         get_created_by( ).
         compare( ).
         WRITE: / 'lines of message: ' , lines( mt_msg_origin ).
         WRITE: / 'test on all Opportunity created by Jerry passed.' COLOR COL_NEGATIVE.
      ENDMETHOD.
      METHOD: test_all_oppt.
         get_oppt_guid( ).
         compare( ).
         WRITE: / 'lines of message: ' , lines( mt_msg_origin ).
         WRITE: / 'test on all Opportunity with type OPPT passed.' COLOR COL_NEGATIVE.
      ENDMETHOD.
    METHOD: get_created_by.
        CLEAR: mt_guid_tab.
        SELECT guid INTO TABLE mt_guid_tab FROM crmd_orderadm_h WHERE created_by = 'WANGJER'.
      ENDMETHOD.
       METHOD: get_oppt_jerry.
        CLEAR: mt_guid_tab.
        SELECT guid INTO TABLE mt_guid_tab FROM crmd_orderadm_h WHERE process_type = 'OPPT' AND created_by = 'WANGJER'.
      ENDMETHOD.
      METHOD: get_oppt_guid.
        CLEAR: mt_guid_tab.
        SELECT guid INTO TABLE mt_guid_tab FROM crmd_orderadm_h WHERE process_type = 'OPPT'.
      ENDMETHOD.
      METHOD: compare.
        CLEAR: mt_msg_origin, mt_msg_opt.
        mt_msg_origin = mo_tool->get_order_error_message_opt( mt_guid_tab ).
        CALL FUNCTION 'CRM_MESSAGES_INIT'
          EXPORTING
            it_docnumber = mt_guid_tab.
        mt_msg_opt = mo_tool->get_order_error_message( mt_guid_tab ).
        SORT mt_msg_origin BY header_guid log_msg.
        SORT mt_msg_opt BY header_guid log_msg.
        ASSERT mt_msg_origin = mt_msg_opt.
      ENDMETHOD.
      METHOD: constructor.
        mo_tool = NEW cl_crm_order_message_tool( ).
      ENDMETHOD.
    ENDCLASS.
    START-OF-SELECTION.
    DATA: lo_test TYPE REF TO lcl_test.
    lo_test = new lcl_test( ).
    lo_test->test_all_oppt( ).
    lo_test->test_created_by_jerry( ).
    lo_test->test_oppt_jerry( ).
    

    要获取更多Jerry的原创文章,请关注公众号"汪子熙":

  • 相关阅读:
    wxPython跨线程调用
    安卓开发24:FrameLayout布局
    URAL 1081
    [置顶] Hibernate运行机理
    [置顶] Hibernate的一个经典异常
    poj1190 生日蛋糕 dfs
    [置顶] 自己写代码生成器之生成Dal层代码(获取数据库所有表名称)
    修改mysql数据存储的地址
    拖延心理学
    DeepLearnToolbox使用总结
  • 原文地址:https://www.cnblogs.com/sap-jerry/p/13639713.html
Copyright © 2011-2022 走看看