Last active
October 21, 2022 09:06
-
-
Save PilotFlying/9e5965c50ed40a9207bfa9dff40e2732 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PROGRAM zlocal_test_it_hash. | |
CLASS gcl_test_runtimes DEFINITION DEFERRED. | |
CLASS gcl_main DEFINITION. | |
PUBLIC SECTION. | |
TYPES: | |
BEGIN OF t_line, | |
field1 TYPE char128, "try type string to raise exception cx_sy_assign_cast_illegal_cast | |
field2 TYPE char128, | |
END OF t_line, | |
tt_lines TYPE STANDARD TABLE OF t_line WITH EMPTY KEY. | |
CLASS-METHODS run_program. | |
ENDCLASS. | |
CLASS gcl_test_runtimes DEFINITION. | |
PUBLIC SECTION. | |
TYPES: | |
t_internal_table_hash TYPE string, | |
BEGIN OF t_measurements, | |
executions TYPE syst-tabix, | |
loop_serialization TYPE i, | |
shortloop_serialization TYPE i, | |
export_serialization TYPE i, | |
sha1_function_module TYPE i, | |
sha2_method TYPE i, | |
END OF t_measurements. | |
CLASS-METHODS: | |
hash_internal_table IMPORTING it TYPE ANY TABLE | |
RETURNING VALUE(rv_hash) TYPE t_internal_table_hash | |
RAISING cx_abap_error_analyze. | |
PROTECTED SECTION. | |
CLASS-METHODS: | |
display IMPORTING is_averages TYPE t_measurements. | |
ENDCLASS. | |
CLASS gcl_main IMPLEMENTATION. | |
METHOD run_program. | |
DATA(lt) = VALUE tt_lines( ( field1 = 'https://blogs.sap.com/2020/01/20/calculate-hash-value-for-internal-table/' | |
field2 = 'Αβγδεζηθικλμπνξοπρστυφχψω' ) | |
( field1 = 'System characters stored in' | |
field2 = |{ cl_abap_char_utilities=>charsize } bytes| ) ). | |
DO 16 TIMES. | |
APPEND LINES OF lt TO lt. "lines( lt ) = 2^17 | |
ENDDO. | |
TRY. | |
gcl_test_runtimes=>hash_internal_table( lt ). | |
CATCH cx_abap_error_analyze INTO DATA(lo_exc). | |
MESSAGE lo_exc->message TYPE lo_exc->kind. | |
ENDTRY. | |
ENDMETHOD. | |
ENDCLASS. | |
CLASS gcl_test_runtimes IMPLEMENTATION. | |
METHOD hash_internal_table. | |
DATA: | |
ls_measurements TYPE t_measurements. | |
DATA: | |
lv_table_line_bytes TYPE xstring, | |
lv_xbuffer TYPE xstring, | |
lv_shortloop_xbuffer TYPE xstring, | |
lv_hash TYPE t_internal_table_hash, | |
lv_sha1_hash TYPE hash160. | |
DO 10 TIMES. | |
CLEAR: | |
lv_xbuffer, lv_shortloop_xbuffer. | |
TRY. | |
GET RUN TIME FIELD DATA(lv_start). | |
LOOP AT it ASSIGNING FIELD-SYMBOL(<ls_line>). | |
DATA(lv_field_index) = 1. | |
CLEAR lv_table_line_bytes. | |
DO. | |
ASSIGN COMPONENT lv_field_index OF STRUCTURE <ls_line> TO FIELD-SYMBOL(<lv_field>) CASTING TYPE x. | |
IF sy-subrc <> 0. | |
EXIT. | |
ENDIF. | |
CONCATENATE lv_table_line_bytes <lv_field> INTO lv_table_line_bytes IN BYTE MODE. | |
lv_field_index = lv_field_index + 1. | |
ENDDO. | |
CONCATENATE lv_xbuffer lv_table_line_bytes INTO lv_xbuffer IN BYTE MODE. | |
ENDLOOP. | |
GET RUN TIME FIELD DATA(lv_end). | |
ls_measurements-loop_serialization = ls_measurements-loop_serialization + ( lv_end - lv_start ). | |
GET RUN TIME FIELD lv_start. | |
LOOP AT it ASSIGNING <ls_line>. | |
ASSIGN COMPONENT 0 OF STRUCTURE <ls_line> TO FIELD-SYMBOL(<lv_all_fields>) CASTING TYPE x. | |
IF sy-subrc <> 0. | |
MESSAGE 'Should be unreachable' TYPE 'X'. | |
ENDIF. | |
CONCATENATE lv_shortloop_xbuffer <lv_all_fields> INTO lv_shortloop_xbuffer IN BYTE MODE. | |
ENDLOOP. | |
GET RUN TIME FIELD lv_end. | |
ls_measurements-shortloop_serialization = ls_measurements-shortloop_serialization + ( lv_end - lv_start ). | |
IF lv_xbuffer <> lv_shortloop_xbuffer. | |
BREAK-POINT. | |
ENDIF. | |
CATCH cx_sy_assign_cast_illegal_cast. "when, e.g., it_table contains string-type fields | |
BREAK-POINT. | |
* EXPORT it = lt TO DATA BUFFER lv_xbuffer COMPRESSION OFF. | |
ENDTRY. | |
GET RUN TIME FIELD lv_start. | |
EXPORT zident = it TO DATA BUFFER lv_xbuffer COMPRESSION OFF. | |
GET RUN TIME FIELD lv_end. | |
ls_measurements-export_serialization = ls_measurements-export_serialization + ( lv_end - lv_start ). | |
GET RUN TIME FIELD lv_start. | |
CALL FUNCTION 'CALCULATE_HASH_FOR_RAW' "SHA1 | |
EXPORTING | |
data = lv_xbuffer | |
IMPORTING | |
hash = lv_sha1_hash | |
EXCEPTIONS | |
unknown_alg = 1 | |
param_error = 2 | |
internal_error = 3 | |
OTHERS = 4. | |
IF sy-subrc <> 0. | |
RAISE EXCEPTION TYPE cx_abap_error_analyze | |
EXPORTING | |
message = |CALCULATE_HASH_FOR_RAW sy-subrc: { sy-subrc }| | |
kind = 'E'. | |
ENDIF. | |
GET RUN TIME FIELD lv_end. | |
ls_measurements-sha1_function_module = ls_measurements-sha1_function_module + ( lv_end - lv_start ). | |
TRY. | |
GET RUN TIME FIELD lv_start. | |
cl_abap_message_digest=>calculate_hash_for_raw( | |
EXPORTING | |
if_algorithm = 'SHA512' "1848999 - Central Note for CommonCryptoLib 8 (SAPCRYPTOLIB) | |
if_data = lv_xbuffer | |
IMPORTING | |
ef_hashstring = lv_hash " Hash value as hex encoded string | |
* ef_hashxstring = ef_hashxstring " Binary hash value as XString | |
* ef_hashb64string = ef_hashb64string " Hash value as base64 encoded string | |
* ef_hashx = ef_hashx " Hash value as XSequence | |
). | |
GET RUN TIME FIELD lv_end. | |
ls_measurements-sha2_method = ls_measurements-sha2_method + ( lv_end - lv_start ). | |
CATCH cx_abap_message_digest INTO DATA(lo_mdx). | |
RAISE EXCEPTION TYPE cx_abap_error_analyze | |
EXPORTING | |
previous = lo_mdx | |
message = |CALCULATE_HASH_FOR_RAW sy-subrc: { sy-subrc }| | |
kind = 'E'. | |
ENDTRY. | |
ls_measurements-executions = ls_measurements-executions + 1. | |
ENDDO. | |
TRY. | |
DATA ls_averages TYPE t_measurements. | |
ls_averages-executions = ls_measurements-executions. | |
DEFINE mav. | |
ls_averages-&1 = ls_measurements-&1 / ls_measurements-executions. | |
end-of-definition. | |
mav: loop_serialization, shortloop_serialization, export_serialization, sha1_function_module, sha2_method. | |
CATCH cx_sy_zerodivide. | |
RAISE EXCEPTION TYPE cx_abap_error_analyze | |
EXPORTING | |
previous = lo_mdx | |
message = |Zero executions?| | |
kind = 'E'. | |
ENDTRY. | |
display( ls_averages ). | |
ENDMETHOD. | |
METHOD display. | |
SELECT SINGLE laiso FROM t002 WHERE spras = @sy-langu INTO @DATA(lv_lang). | |
DATA(lv_html) = |<html lang="{ lv_lang }">| && | |
`<head>` && | |
`<meta name="description" content="https://blogs.sap.com/2020/01/20/calculate-hash-value-for-internal-table/">` && | |
`<style type="text/css">` && | |
`span.cn {font-family: Courier New;}` && | |
`span.ve {font-family: Arial; font-size:-1;}` && | |
`</style>` && | |
`</head>` && | |
`<body>` && | |
|<h3 style="font-family:Verdana">{ is_averages-executions NUMBER = USER } Repetitions </h3>| && | |
'<span class="ve">' && | |
`Average execution times in μs (1 millionth of a second) <br/>` && | |
'</span>' && | |
'<span class="cn">' && | |
|<hr align=left>| && | |
`<table>` && | |
|<tr><th align=left>Operation</th><th align=left>Time</th><th align=right>Speedup</th></tr>| && | |
|<tr><td>Loop serialization:</td><td>{ is_averages-loop_serialization }</td>| && | |
| <td align=right>{ round( val = is_averages-loop_serialization / is_averages-loop_serialization dec = 2 ) }</td></tr><br/>| && | |
|<tr><td>Short loop serialization:</td><td>{ is_averages-shortloop_serialization }</td>| && | |
| <td align=right>{ round( val = is_averages-loop_serialization / is_averages-shortloop_serialization dec = 2 ) }</td></tr><br/>| && | |
|<tr><td>EXPORT serialization:</td><td>{ is_averages-export_serialization }</td>| && | |
| <td align=right>{ round( val = is_averages-shortloop_serialization / is_averages-export_serialization dec = 2 ) }</td></tr><br/>| && | |
|<tr><td> </td><td> </td></tr>| && | |
|<tr><td>SHA-1 Function module:</td><td>{ is_averages-sha1_function_module }</td>| && | |
| <td align=right>{ round( val = is_averages-sha1_function_module / is_averages-sha1_function_module dec = 2 ) }</td></tr><br/>| && | |
|<tr><td>SHA-2 Method:</td><td>{ is_averages-sha2_method }</td>| && | |
| <td align=right>{ round( val = is_averages-sha1_function_module / is_averages-sha2_method dec = 2 ) }</td></tr><br/>| && | |
`</table></br>` && | |
|<hr align=left>| && | |
'</span>' && | |
`</body>` && | |
`</html>`. | |
cl_abap_browser=>show_html( | |
EXPORTING | |
* html = html " HTML Table, Line Width 255 Characters | |
title = 'Loop serialization vs EXPORT' " Window Title | |
size = cl_abap_browser=>medium " Size (S,M.L,XL) | |
* modal = abap_true " Dialog box is modal (else modeless) | |
html_string = lv_html " HTML String | |
printing = abap_true " Key for printing | |
* buttons = navigate_off " Navigation Keys navigate_... | |
format = cl_abap_browser=>portrait " Landscape/portrait format | |
position = cl_abap_browser=>middle " Position | |
* data_table = data_table " External data | |
* anchor = anchor " Goto Point | |
context_menu = abap_true " Display context menu in browser | |
* html_xstring = html_xstring " HTML Binary String | |
* check_html = abap_true " Test of HTML File | |
* container = container " Container for display | |
* dialog = abap_true " Display in dialog box | |
* IMPORTING | |
* html_errors = html_errors " Error List from Test | |
). | |
ENDMETHOD. | |
ENDCLASS. | |
START-OF-SELECTION. | |
gcl_main=>run_program( ). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment