In the Performance of Nested Loops, I showed that nested loops can give far worse performance than a poorly constructed SELECT statement. In Using an Index When You Don't Have all of the Fields, I showed some tricks that will allow you to use an index. In this blog I will look at some other performance tuning tips to see how they stack up against these two.
I wrote four programs to examine this. Each one provides statistics at the end to show how long portions of it took. Each one also includes a small report (that is commented out) that you can produce to ensure that it produces the same report as the other programs. Before you look at them, I should point out some important caveats:
The first two programs may run for a very long time.
The first program disobeys a number of performance rules and is presented below:
report ztest1 line-size 120 message-id 00 line-count 44.
data: bkpf type bkpf, bseg type bseg, lfa1 type lfa1, ekko type ekko, ekpo type ekpo.
select-options: s_lifnr for bseg-lifnr memory id lif obligatory.
types: begin of fi_tab, bukrs type bseg-bukrs, belnr type bseg-belnr, gjahr type bseg-gjahr, buzei type bseg-buzei, lifnr type bseg-lifnr, ebeln type bseg-ebeln, ebelp type bseg-ebelp, budat type bkpf-budat, waers type bkpf-waers, blart type bkpf-blart, usnam type bkpf-usnam, cpudt type bkpf-cpudt, cputm type bkpf-cputm, name1 type kna1-name1, end of fi_tab.
types: begin of po_tab, ebeln type ekpo-ebeln, ebelp type ekpo-ebelp, loekz type ekko-loekz, lifnr type ekko-lifnr, aedat type ekko-aedat, ernam type ekko-ernam, loekz1 type ekpo-loekz, menge type ekpo-menge, netwr type ekpo-netwr, end of po_tab.
types: begin of merge_tab, bukrs type bseg-bukrs, belnr type bseg-belnr, gjahr type bseg-gjahr, buzei type bseg-buzei, name1 type kna1-name1, ebeln type ekko-ebeln, lifnr type ekko-lifnr, ernam type ekko-ernam, waers type bkpf-waers, curr(20), end of merge_tab.
data: fi_int type table of fi_tab, fi_wa type fi_tab, po_int type table of po_tab, po_wa type po_tab, merge_int type table of merge_tab, merge_wa type merge_tab, copy_int type table of merge_tab, copy_wa type merge_tab.
data: pgm_start type sy-uzeit, pgm_end type sy-uzeit, sel1_start type sy-uzeit, sel1_end type sy-uzeit, sel2_start type sy-uzeit, sel2_end type sy-uzeit, merge_start type sy-uzeit, merge_end type sy-uzeit, dif1 type i, dif2 type i, dif3 type i, dif4 type i, no_lines type i.
initialization. perform init_parm.
start-of-selection.
get time field pgm_start.
perform get_fi. perform get_po. perform merge_data. perform copy_itab.
get time field pgm_end. dif4 = pgm_end - pgm_start.
perform write_statistics.
top-of-page. perform write_heading.
&----
----
endform. " init_parm
&----
----
get time field sel1_start.
select * from bseg where gjahr > '2001' and lifnr in s_lifnr and koart = 'K'. move-corresponding bseg to fi_wa.
select single * from bkpf where bukrs = bseg-bukrs and belnr = bseg-belnr and gjahr = bseg-gjahr. if sy-subrc = 0. move-corresponding bkpf to fi_wa. endif.
select single * from lfa1 where lifnr = bseg-lifnr. if sy-subrc = 0. move-corresponding lfa1 to fi_wa. endif.
append fi_wa to fi_int. endselect.
if sy-subrc <> 0. message e001 with 'No FI data selected'. endif.
sort fi_int by bukrs belnr gjahr.
get time field sel1_end. dif1 = sel1_end - sel1_start.
endform. " get_fi
&----
----
get time field sel2_start.
select * from ekko where lifnr in s_lifnr. move-corresponding ekko to po_wa.
select * from ekpo where ebeln = ekko-ebeln. move-corresponding ekpo to po_wa. po_wa-loekz1 = ekpo-loekz. po_wa-aedat = ekko-aedat.
append po_wa to po_int.
endselect. endselect.
if sy-subrc <> 0. message e001 with 'No PO data selected'. endif.
get time field sel2_end. dif2 = sel2_end - sel2_start.
endform. " get_po
&----
----
sort: po_int by lifnr ernam aedat, fi_int by lifnr usnam cpudt.
get time field merge_start.
loop at po_int into po_wa.
loop at fi_int into fi_wa where lifnr = po_wa-lifnr and usnam = po_wa-ernam and cpudt = po_wa-aedat. move-corresponding fi_wa to merge_wa. move-corresponding po_wa to merge_wa. append merge_wa to merge_int. endloop. endloop.
loop at merge_int into merge_wa. if merge_wa-waers = 'CAD'. merge_wa-curr = 'Canadian dollars'. elseif merge_wa-waers = 'USD'. merge_wa-curr = 'U. S. dollars'. elseif merge_wa-waers = 'GBP'. merge_wa-curr = 'British pounds'. elseif merge_wa-waers = 'EUR'. merge_wa-curr = 'Euros'. else. merge_wa-curr = 'Other'. endif.
modify merge_int from merge_wa.
endloop.
get time field merge_end. dif3 = merge_end - merge_start.
endform. " merge_data
&----
----
loop at merge_int into merge_wa. move-corresponding merge_wa to copy_wa. append copy_wa to copy_int. endloop.
delete adjacent duplicates from copy_int comparing bukrs belnr gjahr ebeln.
endform. " copy_itab
&----
----
write: /037 'Test Report to Validate Data Selection'. write: /001 'CoCd', 006 'Doc No', 018 'FYr', 024 'PONo', 036 'Ven No', 052 'Vendor Name', 089 'UserID', 101 'Currency'. skip 1.
endform. " write_heading
&----
----
loop at copy_int into copy_wa. write: / copy_wa-bukrs under 'CoCd', copy_wa-belnr under 'Doc No', copy_wa-gjahr under 'FYr', copy_wa-ebeln under 'PONo', copy_wa-lifnr under 'Ven No', copy_wa-name1 under 'Vendor Name', copy_wa-ernam under 'UserID', copy_wa-curr under 'Currency'. endloop.
if sy-subrc = 0. skip 1. write: /001 'Number of rows selected: ', no_lines. else. write: /001 'No data selected'. endif.
endform. " write_data
&----
----
describe table fi_int lines no_lines. write: /001 'Number of FI records selected :', no_lines.
describe table po_int lines no_lines. write: /001 'Number of PO records selected :', no_lines.
describe table copy_int lines no_lines. write: /001 'Number of merged records :', no_lines.
skip 1. write: /001 'Time for unoptimized select on FI data :', dif1, 'seconds'. write: /001 'Time for unoptimized select on PO data :', dif2, 'seconds'. write: /001 'Time for unoptimized merge of data :', dif3, 'seconds'. write: /001 'Time for unoptimized program :', dif4, 'seconds'.
endform. " write_statistics type fi_tab.
data: pgm_start type sy-uzeit, pgm_end type sy-uzeit, sel1_start type sy-uzeit, sel1_end type sy-uzeit, sel2_start type sy-uzeit, sel2_end type sy-uzeit, merge_start type sy-uzeit, merge_end type sy-uzeit, dif1 type i, dif2 type i, dif3 type i, dif4 type i, no_lines type i.
initialization. perform init_parm.
start-of-selection.
get time field pgm_start.
perform get_fi. perform get_po. perform merge_data. perform copy_itab.
get time field pgm_end. dif4 = pgm_end - pgm_start.
perform write_statistics.
top-of-page. perform write_heading.
&----
----
endform. " init_parm
&----
----
get time field sel1_start.
select bukrs belnr gjahr buzei lifnr ebeln ebelp from bseg into table bseg_int where gjahr > '2001' and lifnr in s_lifnr and koart = 'K'.
if sy-subrc -name1 to fi_wa-name1. endif.
append fi_wa to fi_int. endloop.
sort fi_int by bukrs belnr gjahr.
get time field sel1_end. dif1 = sel1_end - sel1_start.
endform. " get_fi
&----
----
get time field sel2_start.
select ekkoebeln ekpoebelp ekkoloekz ekkolifnr ekko~aedat ekkoernam ekpoloekz ekpomenge ekponetwr from ekko join ekpo on ekpoebeln = ekkoebeln into table po_int where lifnr in s_lifnr.
if sy-subrc <> 0. message e001 with 'No PO data selected'. endif.
get time field sel2_end. dif2 = sel2_end - sel2_start.
endform. " get_po
&----
----
sort: po_int by lifnr ernam aedat, fi_int by lifnr usnam cpudt.
get time field merge_start.
loop at po_int assigning -waers to merge_wa-waers. append merge_wa to merge_int. endloop. endloop.
loop at merge_int into merge_wa. case merge_wa-waers. when 'CAD'. merge_wa-curr = 'Canadian dollars'. when 'USD'. merge_wa-curr = 'U. S. dollars'. when 'GBP'. merge_wa-curr = 'British pounds'. when 'EUR'. merge_wa-curr = 'Euros'. when others. merge_wa-curr = 'Other'. endcase.
modify merge_int from merge_wa transporting curr.
endloop.
get time field merge_end. dif3 = merge_end - merge_start.
endform. " merge_data
&----
----
copy_int[] = merge_int[].
delete adjacent duplicates from copy_int comparing bukrs belnr gjahr ebeln.
endform. " copy_itab
&----
----
write: /037 'Test Report to Validate Data Selection'. write: /001 'CoCd', 006 'Doc No', 018 'FYr', 024 'PONo', 036 'Ven No', 052 'Vendor Name', 089 'UserID', 101 'Currency'. skip 1.
endform. " write_heading
&----
----
describe table copy_int lines no_lines.
loop at copy_int into copy_wa. write: / copy_wa-bukrs under 'CoCd', copy_wa-belnr under 'Doc No', copy_wa-gjahr under 'FYr', copy_wa-ebeln under 'PONo', copy_wa-lifnr under 'Ven No', copy_wa-name1 under 'Vendor Name', copy_wa-ernam under 'UserID', copy_wa-curr under 'Currency'. endloop.
if sy-subrc = 0. skip 1. write: /001 'Number of rows selected: ', no_lines. else. write: /001 'No data selected'. endif.
endform. " write_data
&----
----
describe table fi_int lines no_lines. write: /001 'Number of FI records selected :', no_lines.
describe table po_int lines no_lines. write: /001 'Number of PO records selected :', no_lines.
describe table copy_int lines no_lines. write: /001 'Number of merged records :', no_lines.
skip 1. write: /001 'Time for poorly optimized select on FI data :', dif1, 'seconds'. write: /001 'Time for poorly optimized select on PO data :', dif2, 'seconds'. write: /001 'Time for poorly optimized merge of data :', dif3, 'seconds'. write: /001 'Time for poorly optimized program :', dif4, 'seconds'.
endform. " write_statistics
The third program uses just two techniques. I've jumped through a couple of hoops to make sure I use an index and I've replaced the nested loops with a single loop and binary reads. Here is the final program:
report ztest3 line-size 120 message-id 00 line-count 44.
data: bkpf type bkpf, bseg type bseg, lfa1 type lfa1, ekko type ekko, ekpo type ekpo.
select-options: s_lifnr for bseg-lifnr memory id lif obligatory.
types: begin of fi_tab, bukrs type bseg-bukrs, belnr type bseg-belnr, gjahr type bseg-gjahr, buzei type bseg-buzei, lifnr type bseg-lifnr, ebeln type bseg-ebeln, ebelp type bseg-ebelp, budat type bkpf-budat, waers type bkpf-waers, blart type bkpf-blart, usnam type bkpf-usnam, cpudt type bkpf-cpudt, cputm type bkpf-cputm, name1 type kna1-name1, end of fi_tab.
types: begin of po_tab, ebeln type ekpo-ebeln, ebelp type ekpo-ebelp, loekz type ekko-loekz, lifnr type ekko-lifnr, aedat type ekko-aedat, ernam type ekko-ernam, loekz1 type ekpo-loekz, menge type ekpo-menge, netwr type ekpo-netwr, end of po_tab.
types: begin of merge_tab, bukrs type bseg-bukrs, belnr type bseg-belnr, gjahr type bseg-gjahr, buzei type bseg-buzei, name1 type kna1-name1, ebeln type ekko-ebeln, lifnr type ekko-lifnr, ernam type ekko-ernam, waers type bkpf-waers, curr(20), end of merge_tab.
data: fi_int type table of fi_tab, fi_wa type fi_tab, po_int type table of po_tab, po_wa type po_tab, merge_int type table of merge_tab, merge_wa type merge_tab, copy_int type table of merge_tab, copy_wa type merge_tab, bsik_wa type bsik, bsak_wa type bsak, bkpf_wa type bkpf, lfa1_wa type lfa1, ekko_wa type ekko, ekpo_wa type ekpo.
data: pgm_start type sy-uzeit, pgm_end type sy-uzeit, sel1_start type sy-uzeit, sel1_end type sy-uzeit, sel2_start type sy-uzeit, sel2_end type sy-uzeit, merge_start type sy-uzeit, merge_end type sy-uzeit, dif1 type i, dif2 type i, dif3 type i, dif4 type i, no_lines type i, fi_index type sy-tabix.
initialization. perform init_parm.
start-of-selection.
get time field pgm_start.
perform get_fi. perform get_po. perform merge_data. perform copy_itab.
get time field pgm_end. dif4 = pgm_end - pgm_start.
perform write_statistics.
top-of-page. perform write_heading.
&----
----
endform. " init_parm
&----
----
get time field sel1_start.
select * from bsik into bsik_wa where lifnr in s_lifnr and gjahr > '2001'. move-corresponding bsik_wa to fi_wa.
select single * from bkpf into bkpf_wa where bukrs = bsik_wa-bukrs and belnr = bsik_wa-belnr and gjahr = bsik_wa-gjahr. if sy-subrc = 0. move-corresponding bkpf_wa to fi_wa. endif.
select single * from lfa1 into lfa1_wa where lifnr = bsik_wa-lifnr. if sy-subrc = 0. move-corresponding lfa1_wa to fi_wa. endif.
append fi_wa to fi_int. endselect.
select * from bsak into bsak_wa where lifnr in s_lifnr and gjahr > '2001'. move-corresponding bsak_wa to fi_wa.
select single * from bkpf into bkpf_wa where bukrs = bsak_wa-bukrs and belnr = bsak_wa-belnr and gjahr = bsak_wa-gjahr. if sy-subrc = 0. move-corresponding bkpf_wa to fi_wa. endif.
select single * from lfa1 into lfa1_wa where lifnr = bsak_wa-lifnr. if sy-subrc = 0. move-corresponding lfa1_wa to fi_wa. endif.
append fi_wa to fi_int. endselect.
describe table fi_int lines no_lines.
if no_lines = 0. message e001 with 'No FI data selected'. endif.
sort fi_int by bukrs belnr gjahr.
get time field sel1_end. dif1 = sel1_end - sel1_start.
endform. " get_fi
&----
----
get time field sel2_start.
select * from ekko into ekko_wa where lifnr in s_lifnr. move-corresponding ekko_wa to po_wa.
select * from ekpo into ekpo_wa where ebeln = ekko_wa-ebeln. move-corresponding ekpo_wa to po_wa. po_wa-loekz1 = ekpo_wa-loekz. po_wa-aedat = ekko_wa-aedat.
append po_wa to po_int.
endselect. endselect.
if sy-subrc <> 0. message e001 with 'No PO data selected'. endif.
get time field sel2_end. dif2 = sel2_end - sel2_start.
endform. " get_po
&----
----
sort: po_int by lifnr ernam aedat, fi_int by lifnr usnam cpudt.
get time field merge_start.
loop at po_int into po_wa. read table fi_int with key lifnr = po_wa-lifnr usnam = po_wa-ernam cpudt = po_wa-aedat binary search into fi_wa.
fi_index = sy-tabix.
while sy-subrc = 0. move-corresponding fi_wa to merge_wa. move-corresponding po_wa to merge_wa. append merge_wa to merge_int.
fi_index = fi_index + 1. read table fi_int index fi_index into fi_wa.
if fi_wa-lifnr <> po_wa-lifnr or fi_wa-usnam <> po_wa-ernam or fi_wa-cpudt <> po_wa-aedat. sy-subrc = 9. endif.
endwhile. endloop.
loop at merge_int into merge_wa. case merge_wa-waers. when 'CAD'. merge_wa-curr = 'Canadian dollars'. when 'USD'. merge_wa-curr = 'U. S. dollars'. when 'GBP'. merge_wa-curr = 'British pounds'. when 'EUR'. merge_wa-curr = 'Euros'. when others. merge_wa-curr = 'Other'. endcase.
modify merge_int from merge_wa transporting curr.
endloop.
get time field merge_end. dif3 = merge_end - merge_start.
endform. " merge_data
&----
----
loop at merge_int into merge_wa. move-corresponding merge_wa to copy_wa. append copy_wa to copy_int. endloop.
delete adjacent duplicates from copy_int comparing bukrs belnr gjahr ebeln.
endform. " copy_itab
&----
----
write: /037 'Test Report to Validate Data Selection'. write: /001 'CoCd', 006 'Doc No', 018 'FYr', 024 'PONo', 036 'Ven No', 052 'Vendor Name', 089 'UserID', 101 'Currency'. skip 1.
endform. " write_heading
&----
----
describe table copy_int lines no_lines.
loop at copy_int into copy_wa. write: / copy_wa-bukrs under 'CoCd', copy_wa-belnr under 'Doc No', copy_wa-gjahr under 'FYr', copy_wa-ebeln under 'PONo', copy_wa-lifnr under 'Ven No', copy_wa-name1 under 'Vendor Name', copy_wa-ernam under 'UserID', copy_wa-curr under 'Currency'. endloop.
if sy-subrc = 0. skip 1. write: /001 'Number of rows selected: ', no_lines. else. write: /001 'No data selected'. endif.
endform. " write_data
&----
----
describe table fi_int lines no_lines. write: /001 'Number of FI records selected :', no_lines.
describe table po_int lines no_lines. write: /001 'Number of PO records selected :', no_lines.
describe table copy_int lines no_lines. write: /001 'Number of merged records :', no_lines.
skip 1. write: /001 'Time for better optimized select on FI data :', dif1, 'seconds'. write: /001 'Time for better optimized select on PO data :', dif2, 'seconds'. write: /001 'Time for better optimized merge of data :', dif3, 'seconds'. write: /001 'Time for better optimized program :', dif4, 'seconds'.
endform. " write_statistics TYPE fi_tab.
DATA: pgm_start TYPE sy-uzeit, pgm_end TYPE sy-uzeit, sel1_start TYPE sy-uzeit, sel1_end TYPE sy-uzeit, sel2_start TYPE sy-uzeit, sel2_end TYPE sy-uzeit, merge_start TYPE sy-uzeit, merge_end TYPE sy-uzeit, dif1 TYPE i, dif2 TYPE i, dif3 TYPE i, dif4 TYPE i, no_lines TYPE i, fi_index TYPE sy-tabix.
INITIALIZATION. PERFORM init_parm.
START-OF-SELECTION.
GET TIME FIELD pgm_start.
PERFORM get_fi. PERFORM get_po. PERFORM merge_data. PERFORM copy_itab.
GET TIME FIELD pgm_end. dif4 = pgm_end - pgm_start.
PERFORM write_statistics.
TOP-OF-PAGE. PERFORM write_heading.
&----
----
ENDFORM. " init_parm
&----
----
GET TIME FIELD sel1_start.
SELECT bukrs belnr gjahr buzei lifnr ebeln ebelp FROM bsik INTO TABLE bseg_int WHERE lifnr IN s_lifnr AND gjahr > '2001'.
IF sy-subrc -name1 TO fi_wa-name1. ENDIF.
APPEND fi_wa TO fi_int. ENDLOOP.
SORT fi_int BY bukrs belnr gjahr.
GET TIME FIELD sel1_end. dif1 = sel1_end - sel1_start.
ENDFORM. " get_fi
&----
----
GET TIME FIELD sel2_start.
SELECT ekkoebeln ekpoebelp ekkoloekz ekkolifnr ekko~aedat ekkoernam ekpoloekz ekpomenge ekponetwr FROM ekko JOIN ekpo ON ekpoebeln = ekkoebeln INTO TABLE po_int WHERE lifnr IN s_lifnr.
IF sy-subrc <> 0. MESSAGE e001 WITH 'No PO data selected'. ENDIF.
GET TIME FIELD sel2_end. dif2 = sel2_end - sel2_start.
ENDFORM. " get_po
&----
----
SORT: po_int BY lifnr ernam aedat, fi_int BY lifnr usnam cpudt.
GET TIME FIELD merge_start.
LOOP AT po_int ASSIGNING -aedat. sy-subrc = 9. ENDIF.
ENDWHILE.
ENDLOOP.
LOOP AT merge_int INTO merge_wa. CASE merge_wa-waers. WHEN 'CAD'. merge_wa-curr = 'Canadian dollars'. WHEN 'USD'. merge_wa-curr = 'U. S. dollars'. WHEN 'GBP'. merge_wa-curr = 'British pounds'. WHEN 'EUR'. merge_wa-curr = 'Euros'. WHEN OTHERS. merge_wa-curr = 'Other'. ENDCASE.
MODIFY merge_int FROM merge_wa TRANSPORTING curr.
ENDLOOP.
GET TIME FIELD merge_end. dif3 = merge_end - merge_start.
ENDFORM. " merge_data
&----
----
copy_int[] = merge_int[].
DELETE ADJACENT DUPLICATES FROM copy_int COMPARING bukrs belnr gjahr ebeln.
ENDFORM. " copy_itab
&----
----
WRITE: /037 'Test Report to Validate Data Selection'. WRITE: /001 'CoCd', 006 'Doc No', 018 'FYr', 024 'PONo', 036 'Ven No', 052 'Vendor Name', 089 'UserID', 101 'Currency'. SKIP 1.
ENDFORM. " write_heading
&----
----
DESCRIBE TABLE copy_int LINES no_lines.
LOOP AT copy_int INTO copy_wa. WRITE: / copy_wa-bukrs UNDER 'CoCd', copy_wa-belnr UNDER 'Doc No', copy_wa-gjahr UNDER 'FYr', copy_wa-ebeln UNDER 'PONo', copy_wa-lifnr UNDER 'Ven No', copy_wa-name1 UNDER 'Vendor Name', copy_wa-ernam UNDER 'UserID', copy_wa-curr UNDER 'Currency'. ENDLOOP.
IF sy-subrc = 0. SKIP 1. WRITE: /001 'Number of rows selected: ', no_lines. ELSE. WRITE: /001 'No data selected'. ENDIF.
ENDFORM. " write_data
&----
----
DESCRIBE TABLE fi_int LINES no_lines. WRITE: /001 'Number of FI records selected :', no_lines.
DESCRIBE TABLE po_int LINES no_lines. WRITE: /001 'Number of PO records selected :', no_lines.
DESCRIBE TABLE copy_int LINES no_lines. WRITE: /001 'Number of merged records :', no_lines.
SKIP 1. WRITE: /001 'Time for highly optimized select on FI data :', dif1, 'seconds'. WRITE: /001 'Time for highly optimized select on PO data :', dif2, 'seconds'. WRITE: /001 'Time for highly optimized merge of data :', dif3, 'seconds'. WRITE: /001 'Time for highly optimized program :', dif4, 'seconds'.
ENDFORM. " write_statistics
I ran each program three times: once with a single vendor to pick up a small amount of data; once with a range of vendors to pick up a moderately large amount of data and once with a wide open range of vendors to pick up as much data as possible. And then I ran the programs multiple times.
When selecting small amounts of data, using an index made the select run about 45 times faster. Then, removing nested SELECTs made it run about an extra 15 times faster. So the most important performance consideration is the use of an index. Removing the nested SELECTs also seemed to help, but these results may be skewed by fact that I only ran the highly optimized program once for this situation.
When selecting larger amounts of data, the elimination of nested loops reduced the run time from over an hour and a half to under a second. The use of the index sped the select up by a factor of five or six. Clearly, in this situation, removing nested loops is the most important performance tool. The use of an index will definitely help, but becomes less important as more of the database is selected.
When selecting very large amounts of data, the elimination of nested loops is still the most important performance tool. (I was not able to run either of the first two programs in under a day because of this.) Replacing nested SELECTS with FOR ALL ENTRIES reduced the run time by about a factor of two and so, helped in this case as well. The use of an index really doesn't matter when you're trying to select the whole database.
Remember the initial assumption - you must fix an existing program that performs poorly. In all likelihood you will find that this is from one of three causes:
Depending on the amount of data the program is retrieving, fix the one(s) that are causing the problem(s). While you can always tune a program to run minutes, seconds or just milliseconds faster, at some point, you will run into the point of diminishing returns. It will take you longer to make the program changes than the users will save due to those program changes. You also have to bear in mind that making any changes to an existing program that works carries some dangers. There is always the risk that the changes you make may make the program run faster, but produce incorrect results. Even if the user signs off on these changes, problems may arise later that may be caused by those changes.
In the final analysis, when writing new programs, I try to use as many of the tuning techniques as I can. But if I have a problem with an existing one, I look no further than nested loops and indexes.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
6 | |
5 | |
3 | |
3 | |
2 | |
2 | |
2 | |
2 | |
1 | |
1 |