19 Ağustos 2009 Çarşamba

ABAP : Internal Table Loop Performansi

İç içe loop, sık sık kullandığımız bir yapıdır.
Örneğin, FI tarafında BKPF den okuduğumuz her belgenin BSEG'de ki kalemi için
bir işlem yapmamız gerekebilir.
Bu, en kötü yöntem olarak şöyle yapılabilir; (aslında en kötü değil, zira bazen loop metodunda ki where koşundan hızlı olabiliyor nedenini sonraki yazılarda yayınlıyacağım)

LOOP AT lt_bkpf INTO ls_bkpf.
LOOP AT lt_bseg INTO ls_bseg.
lv_counter = lv_counter + 1.
IF ls_bseg-BUKRS = ls_bkpf-BUKRS AND
ls_bseg-BELNR = ls_bkpf-BELNR AND
ls_bseg-GJAHR = ls_bkpf-GJAHR.
* kodlar *
ENDIF.
ENDLOOP.
ENDLOOP.



burada gereksiz bir çok belgeye girecek ve sistem kaynaklarını epey sömürecektir.


LOOP AT lt_bkpf INTO ls_bkpf.
LOOP AT lt_bseg INTO ls_bseg WHERE
BUKRS = ls_bkpf-BUKRS AND
BELNR = ls_bkpf-BELNR AND
GJAHR = ls_bkpf-GJAHR.
lv_counter = lv_counter + 1.
* kodlar *
ENDLOOP.
ENDLOOP.


burada ki algoritmada nispeten daha az döngü olacaktır ve bir öncekine göre daha hızlı bir yöntemdir çünkü LOOP dan sonra kullandığımız WHERE koşulu döngü sayısını azaltacaktır.
Peki daha fazla hızlandırılamaz mı ? Tabiki hızlandırılır :)
Nasıl mı ?
Mintax'la canım mintaxla bende yıkarım mintaxla.

Çok basit olarak Önce sort ederiz daha sonra BSEG , ITAB'ını read table ile okuyabiliriz.
Loop yaparken cursor mantığını kullanabildiğimiz için, sy-tabix ile ilgili satırı hızlı bir biçimde

alabilirz.
şöyleki

SORT lt_bkpf BY BUKRS BELNR GJAHR.
SORT lt_bseg BY BUKRS BELNR GJAHR.
LOOP AT lt_bkpf INTO ls_bkpf.
READ TABLE lt_bseg TRANSPORTING NO FIELDS WITH KEY
BUKRS = ls_bkpf-BUKRS
BELNR = ls_bkpf-BELNR
GJAHR = ls_bkpf-GJAHR.
CHECK sy-subrc = 0.
LOOP AT lt_bseg INTO ls_bseg FROM sy-tabix.
lv_counter = lv_counter + 1.
* kodlar *
AT END OF GJAHR.
EXIT.
ENDAT.
ENDLOOP.
ENDLOOP.



Yukarıda ki read table metoduna BINARY SEARCH ekleyerek, daha hızlı bir biçimde okuma yapabiliriz :=)
Şöyleki ;

SORT lt_bkpf BY BUKRS BELNR GJAHR.
SORT lt_bseg BY BUKRS BELNR GJAHR.
LOOP AT lt_bkpf INTO ls_bkpf.
READ TABLE lt_bseg TRANSPORTING NO FIELDS WITH KEY
BUKRS = ls_bkpf-BUKRS
BELNR = ls_bkpf-BELNR
GJAHR = ls_bkpf-GJAHR BINARY SEARCH.
CHECK sy-subrc = 0.
LOOP AT lt_bseg INTO ls_bseg FROM sy-tabix.
lv_counter = lv_counter + 1.
* kodlar *
AT END OF GJAHR.
EXIT.
ENDAT.
ENDLOOP.
ENDLOOP.

******* Sonradan gelen edit

Bunu da kendim test ederken buldum, üsttekinden biraz hızlı ama pointer mantığından biraz yavaş sonuç veriyor fakat yine de güzel :=).

LOOP AT lt_bkpf INTO ls_bkpf.
LOOP AT lt_bseg INTO ls_bseg FROM w_index.

IF ls_bseg-belnr NE ls_bkpf-belnr or
ls_bseg-bukrs ne ls_bkpf-bukrs or
ls_bseg-gjahr ne ls_bkpf-gjahr.

w_index = sy-tabix.
EXIT.
else.
* kodlar *
lv_counter = lv_counter + 1.
ENDIF.
ENDLOOP.
endloop.
******* *************************************


field symbol kullanarak (C de ki pointer mantığı) performansı biraz daha artırabiliriz.

SORT lt_bkpf BY BUKRS BELNR GJAHR.
SORT lt_bseg BY BUKRS BELNR GJAHR.
LOOP AT lt_bkpf ASSIGNING <ls_bkpf>
READ TABLE lt_bseg TRANSPORTING NO FIELDS WITH KEY
BUKRS = <ls_bkpf>-BUKRS
BELNR = <ls_bkpf>-BELNR
GJAHR = <ls_bkpf>-GJAHR BINARY SEARCH.
CHECK sy-subrc = 0.
LOOP AT lt_bseg ASSIGNING <ls_bseg> FROM sy-tabix.
lv_counter = lv_counter + 1.
** kodlar **
AT END OF GJAHR.
EXIT.
ENDAT.
ENDLOOP.
ENDLOOP.

kaynak : Ivan Femia.


bitirirken;
Deprem, bizim için "yaşama alışmalıyız" la biten bir cümlenin ilk kelimesidir sadece.Bu günlerde yine sık duyar olduk bu kelimeyi. 17 Ağustos 1999'un deprem görüntüleri geliyor bir yandan, telsiz konuşmaları...
Bu topraklarda çabuk unutulur acı, kederli bir mecburettir sanki acıyı unutmak. Ya o acıyı birinci dereceden yaşayanlar ? Bingöl depreminde ki Anneler mesela ?
İnsan aslında ölür değil mi, çocuğu ölünce?
Unutulmuş olamaz; yatılı okuldan öğrencilerin tabutlarla dağılışı. Bir gece, uykusunda çocukların dağılıveren bir okul binasının altında kalışı, unutulmuş olamaz.

Parasız yatılı başka bir şeydir Doğu'da. Ben görmüştüm, Diyarbakır'da anneler çocuklarını alıp getirip yalvarırlar; "Benimkini de alın okula!", ağlarlar. çünkü, karnı doysun diye. Bu bahtsız topraktan kurtulsun, adam olsun diye. Gelecek kış veremden, sonraki yaz sarılıktan ölmesin diye. Çocuklar giderler. Parasızlıktan ailelerini aylarca görmeye gelemezler. Evlerine döndüklerinde fiyaka yapmak için mahallede birazcık okul formasıyla gezerler. Okulda dayağın en beterini yeseler de, geceleri korkup altlarına etseler de, annelerini çok özleseler de ağızlarını açıp tek bir kelime etmezler. Çünkü onlar, bu toprakların "şanslı" çocukları olduklarını bilirler. Başka "kurtulma" şansları yoktur, sonbahar gelince tıpış tıpış yeniden okula giderler. Ayakkabılarının önleri açılsa da aylarca bunu kimseye söyleyemezler. İncecik enselerinden bir ağır hayat geçer, hiç ses etmezler. Oralarda çocuklar müthiş erken büyürler. Kocaman gözlerinde büyük adamların efkârını gezdirirler. Buralardakiler bunu pek bilmezler.
Belki de bu yüzden çocuklara bol duran isimleri verirler buralarda. Şehabettin, Abdullah, Tacettin... Belki de, öldüklerinde, çocuk oldukları iyice tınlamasın kalanların kulağında diye "amca" isimleri takıyorlar bebeklere!

Siz hiç ölü çocuk gördünüz mü? Tıpkı ölü kuşlara benzerler. Dünyanın en yumuşak şeyidir ölü serçeler, ürkütücü yumuşaktırlar. Artık hiç telaşlı değildirler, göz kapakları bu yüzden ilk kez görünürler. ölü çocuklar da öyledir. Gördünüz mü hiç bilmem, ilk toprağı babaları atar üzerlerine. çocuğunuzun üzerine toprak attığınızı bir kez içinizden geçirsenize...


Yazı; parasız yatılı başka birşeydir doğuda kısmından itibaren Ece Temelkuran'ın çeşitli yazılarını harmanlayarak yazılmıştır.


Bingöl ile başladık şiirimiz de Bingöl ile alakalı olsun;
Kemalettin Kamu'nun Bingöl çobanları isimli şiirinden;

...Anam bir yaz gecesi doğurmuş beni burda
Bu çamlıkta söylemiş son sözlerini babam
Şu karşıki bayırda verdim kuzuyu kurda
"Suna"mın başka köye gelin gittiği akşam...

Hiç yorum yok: