Skip to Content
Author's profile photo Sergio Ferrari

Simple ABAP Benchmark

Related weblogs: Simple Java Benchmark Simple SAP Benchmark – ABAP vs. Java Updated 19/01/2006: I updated the code in order to make it comparable with a Java version. As an SAP Technical consultant I’m often involved in tuning projects. After logging into an SAP system I’m curious to know if the system is basically a powerful one or not. It is often usefull to compare DEV with QAS with PRD systems and also the different application server of the PRD system. It is also usefull to compare R/3 with CRM with SRM and so on… I posted the question in SDN but it seems that no simple ABAP tool is included in a standard SAP system that is able to report which kind of car you are driving (hopefully a Ferrari one). So I decided to share an ABAP that I written in the past. I try to measure: – the CPU looking for primes – the disk speed writing 100MB in the work directory – the RDBMS writing into table SFLIGHT – the RAM allocating a huge internal table and than scanning it sequentially I do not try to measure: – CPU numbers – Application numbers – Buffer quality In the screen shots you can see the Selection Screen and the results collected on my Laptop (Intel centrino 1,8GHz with a SAP NetWeaver Sneak Preview 2004s). Selection screen: image Result: image Follows the ABAP source code:

*&---------------------------------------------------------------------**& Report  ZSIMPLE_BENCHMARK*& Author: Sergio Ferrari*&         ERPTech SpA*& Version: 1.1  - 2006/01/19*& - RDBMS - update SFLIGHT instead of INDX in order to compare to Java*& Version: 1.0  - 2006/01/18*& Title   Simple ABAP Benchmark*&---------------------------------------------------------------------**& This is a simple ABAP utility that perform different kinds of*& stress test against an SAP ABAP instance in order to allow*& basic comparision between different installations/platforms*&---------------------------------------------------------------------**& What about my system?:*&  SFLIGHT is update for carrid = 'ZSF' AND connid BETWEEN 1 AND 100.*&---------------------------------------------------------------------**& Supported releases:*&  from R4.5B*&---------------------------------------------------------------------**& Notes:*&  process is serialized and multiple CPUs or multiple application*&  servers are not fully used...*&---------------------------------------------------------------------**& Texts:*&  title     - Simple ABAP Benchmark*&  Text symbols*&    TIM - Time*&    TST - Units*&  Selection texts*&    CPU - Execute CPU test*&    DB  - Execute RDBMS test*&    FSY - Execute File System test*&    RAM - Execute RAM test*&    TIME_SS -Runtime per UNIT*&---------------------------------------------------------------------*REPORT  zsimple_benchmark.TABLES: sflight.TYPES: timeio_ss(2) TYPE n.SELECTION-SCREEN BEGIN OF BLOCK tim WITH FRAME TITLE text-tim.PARAMETERS: time_ss TYPE timeio_ss DEFAULT '30'.SELECTION-SCREEN END OF BLOCK tim.SELECTION-SCREEN BEGIN OF BLOCK tst WITH FRAME TITLE text-tst.PARAMETERS: cpu AS CHECKBOX DEFAULT 'X'.PARAMETERS: fsy AS CHECKBOX DEFAULT 'X'.PARAMETERS: db  AS CHECKBOX DEFAULT 'X'.PARAMETERS: ram AS CHECKBOX DEFAULT 'X'.SELECTION-SCREEN END OF BLOCK tst.START-OF-SELECTION.  WRITE: / 'Execution time per Unit: ', time_ss, 'seconds'. "#EC NOTEXT  ULINE.  SKIP.* CPU  IF cpu = 'X'.    PERFORM cpu USING time_ss.  ENDIF.* File System  IF fsy = 'X'.    PERFORM file_system USING time_ss.  ENDIF.* RDBMS Update  IF db = 'X'.    PERFORM rdbms_update USING time_ss.  ENDIF.* RAM  IF ram = 'X'.    PERFORM ram USING time_ss.  ENDIF.*&---------------------------------------------------------------------**&      Form  cpu*&---------------------------------------------------------------------**       text*----------------------------------------------------------------------**      -->MAX_EXECUTION_TIME_SS  text*----------------------------------------------------------------------*FORM cpu USING max_execution_time_ss TYPE timeio_ss .  DATA:  time_begin    TYPE t,               " Begin         time_end      TYPE t,               " End         time_elapsed  TYPE t.               " Elapsed time  DATA: l_primes_count TYPE i.  DATA: l_next_primes  TYPE i.  DATA: l_half               TYPE f.  DATA: l_mod                TYPE i.  TYPES: BEGIN OF ty_line,           number TYPE i,  END OF ty_line.  DATA: l_magic TYPE                   ty_line.  DATA: t_magic TYPE STANDARD TABLE OF ty_line.  DATA: l_max_execution_time TYPE t.  ADD max_execution_time_ss TO l_max_execution_time.* Begin of processing  GET TIME FIELD time_begin.* Processing  l_magic-number = 2. APPEND l_magic TO t_magic. l_next_primes = 2.  l_magic-number = 3. APPEND l_magic TO t_magic. l_next_primes = 3.  WHILE time_elapsed <= l_max_execution_time.    ADD 2 TO l_next_primes.                                 "Only odd nu    l_half     = l_next_primes / 2.*   Look for ...    LOOP AT t_magic INTO l_magic FROM 2.      IF l_magic-number >  l_half.        l_magic-number = l_next_primes.        EXIT.      ENDIF.      l_mod = l_next_primes MOD l_magic-number.      IF l_mod = 0. EXIT. ENDIF.    ENDLOOP.    IF l_magic-number = l_next_primes.*     Got it      APPEND l_magic TO t_magic.      ADD 1 TO l_primes_count.    ENDIF.*   Check execution time    GET TIME FIELD time_end.    time_elapsed = time_end - time_begin.  ENDWHILE.* End of processing  DESCRIBE TABLE t_magic LINES l_primes_count.  WRITE : /1  'CPU Power',                                  "#EC NOTEXT           20 '- Primes found: ',                           "#EC NOTEXT           45 l_primes_count.*  LOOP AT t_magic INTO l_magic.*    WRITE: / l_magic-number.*  ENDLOOP.  FREE t_magic.ENDFORM.                    "cpu*&---------------------------------------------------------------------**&      Form  file_system*&---------------------------------------------------------------------**       text*----------------------------------------------------------------------**      -->MAX_EXECUTION_TIME_SS  text*----------------------------------------------------------------------*FORM file_system USING max_execution_time_ss TYPE timeio_ss.  DATA:  time_begin    TYPE t,               " Begin         time_end      TYPE t,               " End         time_elapsed  TYPE t.               " Elapsed time  CONSTANTS: file_name(128) TYPE c VALUE 'StressTest'.  DATA: l_max_block_size(16)  TYPE p.  l_max_block_size = 10 * 1024 * 1024.                     "10 MB per bl  DATA: l_fsys_record(256) TYPE c.  DATA: l_block_size(16)      TYPE p.  DATA: l_tot_size(16)        TYPE p.  DATA: l_max_execution_time TYPE t.  ADD max_execution_time_ss TO l_max_execution_time.  DO 256 TIMES.    CONCATENATE l_fsys_record '0' INTO l_fsys_record.  ENDDO.* Begin of processing  GET TIME FIELD time_begin.* Processing  WHILE time_elapsed <= l_max_execution_time.    OPEN DATASET file_name FOR OUTPUT IN BINARY MODE.    IF sy-subrc NE 0.      WRITE : / 'Error opening file',                       "#EC NOTEXT                file_name, 'SY:-SUBRC=', sy-subrc.      EXIT.    ENDIF.    CLEAR: l_block_size.    WHILE l_block_size < l_max_block_size.      TRANSFER l_fsys_record TO file_name.      ADD 256 TO l_block_size.    ENDWHILE.    ADD l_block_size TO l_tot_size.    CLOSE DATASET file_name.    DELETE DATASET file_name.*   Check execution time    GET TIME FIELD time_end.    time_elapsed = time_end - time_begin.  ENDWHILE.* End of processing  l_tot_size = l_tot_size / 1024 / 1024.  WRITE : /1  'File System - ',                             "#EC NOTEXT           20 '- Written Mbytes: ',                         "#EC NOTEXT           45(11) l_tot_size.ENDFORM.                    "file_system*&---------------------------------------------------------------------**&      Form  rdbms_update*&---------------------------------------------------------------------**       text*----------------------------------------------------------------------**      -->MAX_EXECUTION_TIME_SS  text*----------------------------------------------------------------------*FORM rdbms_update USING max_execution_time_ss TYPE timeio_ss.  DATA:  time_begin    TYPE t,               " Begin         time_end      TYPE t,               " End         time_elapsed  TYPE t.               " Elapsed time  CONSTANTS: l_carrid  TYPE s_carr_id VALUE 'ZSF'.  DATA     : l_connid  TYPE s_conn_id VALUE 1.  DATA:    : l_sflight TYPE sflight.  DATA: l_rdbms_record(256) TYPE c.  DATA:  l_updated_records  TYPE i.  DATA: l_max_execution_time TYPE t.  ADD max_execution_time_ss TO l_max_execution_time.* Fill record  l_sflight-carrid      = l_carrid.  l_sflight-connid      = l_connid.  l_sflight-fldate      = '20060119'.  l_sflight-price       = 100.  l_sflight-currency    = 'EUR'.  l_sflight-planetype   = 'A319'.  l_sflight-seatsmax    = 100.  l_sflight-seatsocc    = 89.  l_sflight-paymentsum  = 1499.*  l_sflight-seatsmax_b  = 0.*  l_sflight-seatsocc_b  = 0.*  l_sflight-seatsmax_f  = 0.*  l_sflight-seatsocc_f  = 0.* Begin of processing  GET TIME FIELD time_begin.* Processing  WHILE time_elapsed <= l_max_execution_time.    l_sflight-connid = 1.    DELETE FROM sflight WHERE carrid = 'ZSF'                          AND connid BETWEEN 1 AND 100.    DO 100 TIMES.      ADD 1 TO l_sflight-connid.      INSERT sflight FROM l_sflight.    ENDDO.    COMMIT WORK.    ADD 100 TO l_updated_records.*   Check execution time    GET TIME FIELD time_end.    time_elapsed = time_end - time_begin.  ENDWHILE.  DELETE FROM sflight WHERE carrid = 'ZSF'                        AND connid BETWEEN 1 AND 100.  COMMIT WORK.* End of processing  WRITE : /1  'RDBMS update',                               "#EC NOTEXT           20 '- Updated records: ',                        "#EC NOTEXT           45 l_updated_records.ENDFORM.                    "rdbms_ιpdate*&---------------------------------------------------------------------**&      Form  ram*&---------------------------------------------------------------------**       text*----------------------------------------------------------------------**      -->MAX_EXECUTION_TIME_SS  text*----------------------------------------------------------------------*FORM ram USING max_execution_time_ss TYPE timeio_ss.  DATA:  time_begin    TYPE t,               " Begin         time_end      TYPE t,               " End         time_elapsed  TYPE t.               " Elapsed time  TYPES: BEGIN OF ty_line,           key(10)   TYPE n,           attr1(256) TYPE c,           attr2(256) TYPE c,         END OF ty_line.  DATA: line TYPE ty_line.  DATA: itab TYPE STANDARD TABLE OF ty_line.  DATA: l_key(10) TYPE n.  DATA: l_table_scans TYPE i.  DATA: l_max_execution_time TYPE t.  ADD max_execution_time_ss TO l_max_execution_time.  line-attr1 = line-attr2 = 'ABCDEFGHILMNOPQRSTUVZ'.  DO 1000000 TIMES.    l_key = 1000000 - sy-index.    line-key = l_key.    APPEND line TO itab.  ENDDO.* Begin of processing  GET TIME FIELD time_begin.* Processing  WHILE time_elapsed <= l_max_execution_time.    READ TABLE itab INTO line WITH KEY key = 1.    l_table_scans = sy-index.*   Check execution time    GET TIME FIELD time_end.    time_elapsed = time_end - time_begin.  ENDWHILE.* end of processing  WRITE : /1  'RAM',           20 '- Table scans: ',                            "#EC NOTEXT           45 l_table_scans.  FREE itab.ENDFORM.                    "ram

Assigned Tags

      19 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Will Livermore
      Will Livermore
      Sergio,
      Can you please comment on what you have found in your usage of this application to be the values/range of a "fast" system and those of a system you feel is too "slow".

      Regards,
      Will

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      For the moment I can just share same test cases performed on test machines (INTEL).
      Maybe in the future I'll be allowed to publish the whole collection.

      Running with default parameters:
      Linux/Oracle
      .CPU highest prime: 14.552
      .File system - MB :  1.560
      .RDBMS - records  :  5.188
      .RAM - scans      :    133
      Laptop/MaxDB
      .CPU highest prime:  6.094
      .File system - MB :  1.620
      .RDBMS - records  :  5.600
      .RAM - scans      :     87
      Windows/Oracle
      .CPU highest prime: 15.984
      .File system - MB :    530
      .RDBMS - records  :  2.818
      .RAM - scans      :    241

      Yours are welcome...

      Author's profile photo Paul Walmsley
      Paul Walmsley
      I ran it on two test systems :
      windows/sqlserver
      CPU Highest prime number:       8.099
      File System MB:                   550
      RDBMS records:                  9.225
      RAM  scans:                        72

      windows/sqlserver
      CPU Highest prime number:       7.543
      File System MB:                   330
      RDBMS  records:                 7.739
      RAM  scans:                        78

      Author's profile photo Former Member
      Former Member
      Hi

      On AIX/DB2 the reports give the following values
      Execution time per Unit:  30 seconds
      CPU Power -Primes found:  12.154
      File System - Written Mbytes:  2.500
      RDBMS update - Updated records:  179.400
      RAM - Table scans:  96

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Thanks for your contribution.
      DB2 really perform well...
      As reported in the begin of the weblog I updated the code in order to compare the RDBMS with Java.
      So the test performed by Javier Jimenez is valid but the older should be update.
      Here are my updates:
      ABAP
      --------------------------
      Linux/Oracle
      .CPU highest prime: 14.552
      .File system - MB :  1.560
      .RDBMS - records  : 29.800
      .RAM - scans      :    133
      Laptop/MaxDB
      .CPU highest prime:  6.094
      .File system - MB :  1.620
      .RDBMS - records  : 83.400
      .RAM - scans      :     87
      Author's profile photo Athanassios Kitselis
      Athanassios Kitselis
      I know I am 5 years late, but here are the results for a new DELL based Hyper-V server

      Transaktion:    SE38
      Prozessor(s):   AMD64 Level 6 (Mod 23 Step 6)
      Host:           HQNOSAPDEV
      OS:             Windows NT
      DB:             MSSQL
      DB-Release:     10.50.2425
      SAP-Release:    701
      Execution time per Unit:  30 seconds

      CPU Power          - Primes found:         23.870
      File System -      - Written Mbytes:        3.140
      RDBMS update       - Updated records:     160.300
      RAM                - Table :                  239

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      and the Moore's law matters (http://en.wikipedia.org/wiki/Moore's_law) and it seems your system is performing very well especially about the DB subsystem.
      I see that you're running on MS SQL server that with this kind of test (INDX update) seems very better than Oracle. DB2 is also quite fast in this kind of operation.

      Thanks for sharing
      Sergio

      Author's profile photo Uwe Gloss
      Uwe Gloss
      On a HP DL385G4 with SLES9-2 ORA9206 I got:

      23.01.2006                                                              
      -------------------------------------
      Execution time per Unit:  30 seconds
      -------------------------------------

      CPU Power          - Primes found:            21.367
      File System -      - Written Mbytes:             2.680
      RDBMS update       - Updated records:          104.400
      RAM                - Table scans:                  174

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Thanks Uwe...
      Your system is performing very well.
      Javier reported a better performance (much higer) only for the RDBMS update speedy (DB2 >>> Oracle?).
      Your CPU is very fast; is it an AMD?

      Author's profile photo Former Member
      Former Member
      Hi @ all,
      here are my results, i added some lines, to get a little more information:

      Prozessors:4x Intel 801586 (Mod 5 Step 10)       
      OS:Windows NT                            
      DB:Oracle                                     
      DB-Release:8.1.7.4.1                             
      SAP-Rel.:46C                                   

      CPU Power highest number: 15.734
      File System Mbytes:        1.110
      DB Updated records:       17.074
      RAM Table Scans:             186
                                                       
      Runtime: 00:02:05                          

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Thanks Andreas,
        you are right, added lines are very useful to compare results.
        You got high performance in the RAM Table Scans (internal table scan)...
      Author's profile photo Former Member
      Former Member
      Hi sergio,
      i will just copy the few lines i added to get the additional information, so that people don't need to look it up:

      ****Includes
      INCLUDE LSHSYTOP.

      ****Data declaration
      DATA:
      BEGIN OF VERSION_INFO OCCURS 0,
        LINE(80),
      END OF VERSION_INFO.

      DATA:
      OWNLIB(10) TYPE C,
      DATABASE_RELEASE(10),
      MACHINETYP(50) TYPE C.

      ****get release info
      SVERSI-SAPRL = SYST-SAPRL.

      CALL 'SAPCORE' ID 'ID' FIELD 'VERSION'
         ID 'TABLE' FIELD VERSION_INFO-*SYS*.

      ****get status info
      CALL 'GET_PARAM_TCOD' ID 'PTCOD' FIELD
                             SHKONTEXT-TCODE.
      CLEAR MACHINETYP.
      READ TABLE VERSION_INFO INDEX  3.
      MACHINETYP = VERSION_INFO-LINE+21(50).
      READ TABLE VERSION_INFO INDEX  5.
      STATUS_INFO-SYSTEM_ID = VERSION_INFO-LINE+21(10).
      READ TABLE VERSION_INFO INDEX  8.
      STATUS_INFO-DATABASE_HOST =
                     VERSION_INFO-LINE+21(10).
      READ TABLE VERSION_INFO INDEX  9.
      STATUS_INFO-DATABASE_OWNER =
                      VERSION_INFO-LINE+21(10).

      ****get db release
      CALL FUNCTION 'DB_GET_RELEASE'
      IMPORTING
      RELEASE = STATUS_INFO-DATABASE_RELEASE.

      ****output
      WRITE:/ 'Transaktion:', 17 SHKONTEXT-TCODE.
      WRITE:/ 'Prozessor(s):', 17 MACHINETYP.
      WRITE:/ 'Host:', 17 STATUS_INFO-DATABASE_HOST.
      WRITE:/ 'OS:', 17 SY-OPSYS.
      WRITE:/ 'DB:', 17 SYST-DBSYS.
      WRITE:/ 'DB-Release:',
               17 STATUS_INFO-DATABASE_RELEASE.
      WRITE:/ 'SAP-Release:', 17 SY-SAPRL.

      ****end of mod

      Author's profile photo Former Member
      Former Member
      Thanks Andreas, I imported the code and it's tricky and professional.
      I commented out the REPORT statement substituting it with the include lshsytop.
      ----------------------------
      *REPORT  zsimple_benchmark.
      *****Includes
        INCLUDE lshsytop.
      ----------------------------

      It would be nice if the report will be included in the next standard SAP releases...

      SAP could implement also parallel processing as in ERPTech we did... (but I cannot share it).

      Author's profile photo Former Member
      Former Member
      Thanks Andreas, I imported the code and it's tricky and professional.
      I commented out the REPORT statement substituting it with the include lshsytop.
      ----------------------------
      *REPORT  zsimple_benchmark.
      *****Includes
        INCLUDE lshsytop.
      ----------------------------

      It would be nice if the report will be included in the next standard SAP releases...

      SAP could implement also parallel processing as in ERPTech we did... (but I cannot share it).

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Thanks Andreas, I imported the code and I just commented out the REPORT statement substituting it with the include lshsytop.
      ----------------------------
      *REPORT  zsimple_benchmark.
      *****Includes
        INCLUDE lshsytop.
      ----------------------------

      It would be nice if the report will be included in the next standard SAP releases...

      SAP could implement also parallel processing as in ERPTech we did... (but I cannot share it).

      Author's profile photo Former Member
      Former Member
      Hi Sergio,

      Since more than 10 years SAP offers and certifies SAP Standard Application Benchmarks. SAP Technology Partners run SAP benchmarks to show
      the scalability of their systems and to compare the power and performance of different hardwares. SAP benchmarks scale very well and can be used from small systems to very large configurations. You can visit SAP's public web site www.sap.com/benchmark to obtain information about the available SAP benchmarks (for example, BI, APO, TRBK, Portal...).

      Moreover, the Sales & Distribution (SD) benchmark defines the hardware independent unit SAP Application Performance Standard (SAPS) that
      describes the performance of a system configuration in the SAP environment. 100 SAPS is defined as 2,000 fully business processed order
      line items per hour where fully business processed means the full business process of an order line item: creating the order, creating a
      delivery note for the order, displaying the order, changing the delivery, posting a goods issue, listing orders, and creating an invoice. The average response for SD benchmark users must be below 2 seconds.

      On www.sap.com/benchmark you can find SAPS numbers for a variety of different platforms, see the SD two-tier and SD three-tier benchmark result tables.
       
      Business processes of different solutions (CRM, SCM, SRM,...) finally all meet on the persistence layer of the SAP NetWeaver Application Server causing standard operations such as INSERT, UPDATE, DELETE. There are two flavors: ABAP and Java. If you run benchmarks and performance measurements on the same hardware you can receive load factors and algorithms for the different solutions and you can relate this to SAPS.
      I would recommend to read also the Weblog about Efficient SAP Hardware Sizing: Quick Sizer because sizing is based on this behavior.

      Kind regards,
      Birgit Sabaschus

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Hi Birgit, I know that this is a "Simple" Benchmark and it is.

      Professional Benchmarks are certified by SAP and published at www.sap.com/benchmark.
      But what about if an existing system is not well installed/configured (eg. wrongly defined RAID on disks, zero Administration toolkit not active, RDBMS logs not well splitted,...)

      Running SAP standard benchmarks in customer' systems is not so easy; there are always problems with authorization for business transactions,  updating the database and so on...

      SAP standard benchmarks are perfect when you are planning for a new system but are not so useful to verify an existing one (expecially if productive).

      Just 2 minutes and with the proposed utility you can understand what a kind of system your is... (I just update table SFLIGHT for CARRID 'ZSF'...

      Author's profile photo Former Member
      Former Member
      Hi Sergio,

      Good performance is if the performance metrics match your needs or Service Level Agreements.
      A question would be how can you rate the values of your benchmark report being good or bad if you have just a few systems to compare?
      In addition the values of your benchmark report say nothing about good performance of your business processes because there isn't any mapping to business scenario throughput. So you
      can not check if this matches your requirements.

      How would I proceed:
      The business throughput expectations have to be translated into actual hardware resource consumption, for example using the SAP Quick Sizer. So assuming that the sizing is correct
      and the hardware was bought following the sizing recommendations. Unexpectedly the hardware shows a poor performance for the business processes. So something is wrong with the system. To determine
      the cause of the bad performance I would use the SAP standard monitoring tools such as transaction ST03 (Workload Analysis) or ST05 (Performance Analysis SQL Trace). They can show me the bottleneck in my system without implementing additional coding.

      Regards,
      Birgit

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Hi Birgit,
      in the weblog introduction I described why I shared the utility.