Tuesday, December 16, 2008

Efficiency versus Effort - The Eff Debate

A lot of inefficient code is developed from ignorance and laziness. This is so good for hardware vendors that they have established a school of thought that says it's easier to upgrade than to make the code faster. If users really cared about performance, we wouldn't have the explosion of internet applications, or the idea that Office running on the internet ala Googledocs is an improvement.

In spite of all this evidence, I still have a deep abhorrance of needlessly wasted processor cycles. In the world of custom SAP development, most sites can easily double the performance of their custom code by simply having an expert tune it. Even (especially?) SAP developed code can appear to prefer obfuscation over efficiency. It is a tough place for people who see coding as a minimilst artform, constantly striving for irreducible perfection.

There are times, though, when elegance trumps efficiency. In the code below, I have preferred unnecessary calls to LAST_DAY_IN_PERIOD_GET to preserve the integrity of the case statement as the sole logic to determine intervals. Do you agree? It would also be possible to put the periods into a table (array for any non-SAP people reading this, shocked that COBOL is making a comeback - we call it ABAP). But for such a small number of intervals it is more readable like this.


*&---------------------------------------------------------------------*
*& Form SET_AGE
*&---------------------------------------------------------------------*
form set_age
using p_end type d
changing p_agerq type ysd_agerq.

constants:
c_periv type tkel-periv value 'G1'.

statics:
ld_age0003 type d,
ld_age0406 type d,
ld_age0709 type d,
ld_age1012 type d.

data:
lv_enddate type d,
lv_horizon type i,
lv_period type jahrper.

*-- set up static dates
if ld_age0003 is initial.

lv_period = p_per.

do 12 times.

lv_horizon = sy-index.

call function 'RKE_GET_NEXT_PERIOD'
exporting
perio = lv_period
periv = c_periv
importing
nextperio = lv_period
exceptions
i_error = 1
i_perflag_invalid = 2
i_periv_notfound = 3
others = 4.
if sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.

call function 'LAST_DAY_IN_PERIOD_GET'
exporting
i_gjahr = lv_period+0(4)
i_periv = c_periv
i_poper = lv_period+4(3)
importing
e_date = lv_enddate
exceptions
input_false = 1
t009_notfound = 2
t009b_notfound = 3
others = 4.

if sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.

case lv_horizon.
when 3.
ld_age0003 = lv_enddate.
when 6.
ld_age0406 = lv_enddate.
when 9.
ld_age0709 = lv_enddate.
when 12.
ld_age1012 = lv_enddate.
endcase.
enddo.
endif.

*-- Allocate this date to a period range
if p_end le ld_age0003.
p_agerq = '00-03'.
elseif p_end le ld_age0406.
p_agerq = '04-06'.
elseif p_end le ld_age0709.
p_agerq = '07-09'.
elseif p_end le ld_age1012.
p_agerq = '10-12'.
else.
p_agerq = '12+'.
endif.

endform. " SET_AGE

No comments: