Skip to Content
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
To report this post you need to login first.

19 Comments

You must be Logged on to comment or reply to a post.

  1. 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

    (0) 
    1. Sergio Ferrari 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…

      (0) 
      1. 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

        (0) 
        1. Javier Jimenez
          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

          (0) 
          1. Sergio Ferrari 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
            (0) 
            1. 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

              (0) 
              1. Sergio Ferrari 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

                (0) 
  2. 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

    (0) 
    1. Sergio Ferrari 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?

      (0) 
  3. Andreas Brinkmann
    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                          

    (0) 
    1. Sergio Ferrari 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)…
      (0) 
      1. Andreas Brinkmann
        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

        (0) 
        1. Community User
          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).

          (0) 
        2. Community User
          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).

          (0) 
        3. Sergio Ferrari 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).

          (0) 
  4. Birgit Sabaschus
    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 http://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 http://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

    (0) 
    1. Sergio Ferrari Post author
      Hi Birgit, I know that this is a “Simple” Benchmark and it is.

      Professional Benchmarks are certified by SAP and published at http://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’…

      (0) 
      1. Birgit Sabaschus
        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

        (0) 

Leave a Reply