26.09.2022
Lukas Plastinkin

Kodėl Collections naudingos Progress OpenEdge kūrime?

Progress OpenEdge jau turėjo ribotą Collections įgyvendinimą su OpenEdge.Core.Collections paketu. 2022 metų pradžioje buvo išleista Progress OpenEdge 12.5 versija, kuri atnešė integruotą sąrašo (list) kolekcijos konstruktą, kurį gali naudoti bet kuri ABL programa.

Šiame blogo įraše paaiškiname, kas yra kolekcijos Progress OpenEdge aplinkoje, ir kaip Progress.Collections paketas (pristatytas 12.5 versijoje) pagerina programų kūrimą.

Kas yra kolekcija (Collection)?

Kolekcija yra klasė, atspindinti to paties tipo objektų grupę.

Galite ją įsivaizduoti panašiai kaip temp-table, tačiau vietoj įrašų ji saugo objektus. Kadangi kolekcija pati yra objektas, ji taip pat suteikia metodus elementams pridėti, pašalinti ir per juos iteruoti.

Progress OpenEdge 12.5 versijoje "List" tipo kolekcija buvo įgyvendinta, pridėjus šešias integruotas klases ir sąsajas:

  • Progress.Collections.ICollection<T> sąsaja
  • Progress.Collections.IIterable<T> sąsaja
  • Progress.Collections.IIterator<T> sąsaja
  • Progress.Collections.IList<T> sąsaja
  • Progress.Collections.List<T> klasė
  • Progress.Collections.ListIterator<T> klasė

Kita savybė, veikianti kartu su šiomis naujomis klasėmis, – nauja sintaksė, kurioje tipo parametrai apibrėžiami kampiniuose skliaustuose (<T>, kaip matyti aukščiau). Ši savybė naudojama generinio tipo aprašymui.

Kodėl kolekcijos naudingos objektiškai orientuotose programose?

Savybės, kurios bus naudingos kuriant sąrašą savo kode:

  • Supaprastintas procesas. Kolekcijos pašalina poreikį naudoti temp-tables ar rašyti savo duomenų struktūras, sumažindamos programuotojo pastangas ir kodo apimtį.
  • Pažįstamas kodas. Su kolekcijomis galite supaprastinti kodo sintaksę, kuri iškart bus pažįstama tiems, kurie įpratę rašyti objektiškai orientuotą kodą.
  • Lengva naudoti su kitomis technologijomis. Kolekcijos taip pat gali būti naudojamos duomenų struktūroms serializuoti, leidžiant lengvą sąveiką tarp Progress OpenEdge ir kitų technologijų. Serializacija – tai objekto konvertavimas a) į baitų srautą, saugomą atmintyje; b) į failą, kurį prireikus galima atkurti kitur. Jei jūsų programa padalinta į kelias dalis su skirtingomis technologijomis, kolekcijos gali žymiai sumažinti pastangas, reikalingas duomenų perdavimui tarp tų dalių sukonfigūruoti.

Susipažinkite su kodu

Žemiau rasite kodo fragmentą, parodantį darbo su "List" tipo kolekcijomis pagrindus. Jis apima sąrašo kūrimą, objektų pridėjimą ir "Iterator" klasės naudojimą saugomiems objektams pereiti.

Žemiau pateiktas kodo fragmentas – puikus pradinis taškas išbandyti kolekcijas Progress OpenEdge aplinkoje. Daugiau apie kolekcijas ir kitas 12.5 versijoje pridėtas savybes sužinokite, perskaitę išleidimo pastabas apie kolekcijas objektiškai orientuotoje ABL kalboje.

BLOCK-LEVEL ON ERROR UNDO, THROW.  

VAR Progress.Collections.List<Order> orderList.  
VAR Progress.Collections.IIterator<Order> orderIterator.  
VAR order AnyOrder.    

// Create the list  
orderList = NEW Progress.Collections.List<Order>().  

FOR EACH Order NO-LOCK WHERE  
        Order.SalesRep = "HXM":  
   // Add elements to the list  
   orderList:Add(NEW Order(Order.OrderNum)).  
END.  

// Retrieve the first element from the list  
AnyOrder = orderList:Get(1).  

// Replace the first element in the list  
orderList:Set(2, NEW Order(10000)).  

// Remove the second element from the list  
orderList:RemoveAt(3). 

// Print out some information  
MESSAGE 
   "orderList info"  
   orderList:Count  
   orderList:Contains(AnyOrder)  
   orderList:IndexOf(AnyOrder)  
   orderList:Get(4):orderStatus  
   .  

// Iterate over the entries in the list  
orderIterator = orderList:GetIterator().  
REPEAT WHILE orderIterator:MoveNext():  
   orderIterator:Current:calcItems().  
   orderIterator:Current:calcTotalPrice().  
END.  

DEFINE VARIABLE myFileOutStream AS Progress.IO.FileOutputStream.  
DEFINE VARIABLE mySerializer AS Progress.IO.JsonSerializer.    

mySerializer = NEW Progress.IO.JsonSerializer(FALSE).    

/* Serialize object */  
myFileOutStream = NEW Progress.IO.FileOutputStream("OrderList.json").   

mySerializer:Serialize(orderList, myFileOutStream).  
myFileOutStream:Close(). 

/* Also, possible to serialise to memptr */  
DEFINE VARIABLE memptrVar AS MEMPTR NO-UNDO.  
DEFINE VARIABLE myMemoryOutStream AS Progress.IO.MemoryOutputStream.    

myMemoryOutStream = NEW Progress.IO.MemoryOutputStream().  
mySerializer:Serialize(orderList, myMemoryOutStream).  
memptrVar = myMemoryOutStream:Data.   

Veikimo testavimas: temp-table vs kolekcija

Atlikome ribotą temp-table ir kolekcijos veikimo palyginimo testavimą.

Testai buvo atlikti asmeniniuose darbo kompiuteriuose tiek "Windows", tiek "Linux" operacinėse sistemose. Kai kurie testai apėmė didelio duomenų kiekio skaitymą iš CSV failų, jų pridėjimą į temp-tables/sąrašus ir operacijų atlikimą su šiomis duomenų struktūromis. Kiekvieno proceso trukmė buvo matuojama milisekundėmis.

Apskritai veikimas buvo panašus. Tačiau kai kuriais atvejais pastebėti pastebimi veikimo skirtumai tarp "Linux" ir "Windows" operacinių sistemų. Deja, dėl riboto testavimo masto negalime pasakyti, ar tai optimizavimo problema, koks nors klaida (bug), operacinės sistemos savitumas, ar techninės įrangos ypatybė.

Verta paminėti ir tai, kad 12.5 versijoje yra klaida, ribojanti maksimalų objektų skaičių sąrašo kolekcijoje (mūsų atveju tai buvo ~4105 objektai). Tai buvo ištaisyta 12.5.1 versijoje.

Žemiau pateikiama atlikto testo lentelė:

Aprašymas Testo tipas / matuojamas rodiklis Temp-table Windows List Windows Temp-table Linux List Linux
1 testų grupė
Duomenų perkėlimas iš didelio failo (4 tūkst.+ eilučių, 250+ stulpelių) į vieno sluoksnio objektų sąrašą Įrašų kūrimas: 'create ttDwhLoan / thelist:Add(new Loan' ~35 ms ~1700 ms ~23 ms ~90 ms
Duomenų importavimas naudojant 'import delimiter "#"' ~305 ms ~260 ms
Įrašų kūrimas ir reikšmių priskyrimas iš įrašų ~1130 ms ~2680 ms ~700 ms ~670 ms
Iteravimas, kol reikšmė atitiko eilutę apie 3 tūkst. indekse ~23 ms ~13 ms ~7 ms ~8 ms
2 testų grupė
Ankstesniuose testuose sukurtų sąrašų serializavimas ir deserializavimas Serializavimas į .bin tipo failą ~400 ms + ~1200 ms ~170 ms + ~200 ms
Serializavimas į .json tipo failą ~1200 ms + ~2700 ms ~980 ms + ~820 ms
Darbas su sports2020.Order ir sports2020.OrderLine, sukuriant du hierarchijos sluoksnius (daug-su-daug, 18 tūkst.+ įrašų iš viso) Dviejų temp-tables/objektų užpildymas ~250 ms ~4300 ms ~205 ms ~510 ms
Konkretaus lauko reikšmės paieška konkrečiam OrderLine be temp-table indekso ~2 ms ~7 ms ~1 ms ~5 ms
3 testų grupė
4 tūkst. eilučių duomenų perdavimas procedūrai 20 kartų (nenaudojant "by-reference") Bendras kvietimų grandinės laikas 'input table / input thelist' ~1000 ms ~4 ms ~400 ms ~1 ms
30 tūkst. eilučių duomenų perdavimas procedūrai 20 kartų (nenaudojant "by-reference") Atminties naudojimas 'input table / input oList' Mažiau nei 1 MB Mažiau nei 1 MB Mažiau nei 1 MB Nepastebimas padidėjimas

 

Įžvalgos po testavimo

Veikimo testavimas atskleidė tris išvadas:

  • 1 testų grupė: temp-tables gali būti efektyvesnės skaitant didelius tekstinius failus, ir tam tikrais atvejais „Windows“ sistemoje, tačiau apskritai kolekcija veikia gerai.
  • 2 testų grupė: temp-tables gali turėti veikimo pranašumą dirbant su dideliu įrašų kiekiu. Duomenų paieška su objektais veikia gana gerai, atsižvelgiant į pilną perėjimą (full scan).
  • 3 testų grupė: kolekcijos turėtų turėti reikšmingą pranašumą, jei temp-table neperduodama nuoroda (by reference).

Jei jums reikia pagalbos kuriant Progress OpenEdge programas, „Baltic Amadeus“ komanda pasiruošusi atsakyti į jūsų klausimus.

Dažniausiai užduodami klausimai

Kas yra Collection Progress OpenEdge aplinkoje?

Collection – tai klasė, atspindinti to paties tipo objektų grupę, panaši į temp-table, bet saugo objektus, o ne įrašus. Ji taip pat suteikia metodus elementams pridėti, pašalinti ir per juos iteruoti.

Kokia versija pristatė integruotą List tipo kolekciją?

Integruota „List“ tipo kolekcija buvo pristatyta Progress OpenEdge 12.5 versijoje, pridėjus šešias naujas klases ir sąsajas Progress.Collections pakete.

Kas greičiau – temp-table ar kolekcija?

Tai priklauso nuo atvejo. Temp-tables paprastai efektyvesnės skaitant didelius failus ar dirbant su dideliu įrašų kiekiu, o kolekcijos turi reikšmingą pranašumą, kai duomenys perduodami procedūroms nenaudojant „by-reference“.

Kodėl verta naudoti kolekcijas vietoj temp-tables?

Kolekcijos supaprastina kodą, mažina jo apimtį, yra pažįstamos programuotojams, įpratusiems prie objektiškai orientuoto programavimo, ir palengvina duomenų serializavimą sąveikai su kitomis technologijomis.

Pasikalbėkime apie jūsų projektą

Pradedate projektą arba norite sustiprinti jau vykdomą? Susisiekite ir atsakysime jums per vieną darbo dieną.

Parašykite mums

Ačiū! Jūsų pateikimas gautas!
Oi! Pateikiant formą kažkas nutiko.