Zoek

Uitgebreid zoeken Artikelen per auteur

  

Performance Lab #2 : CustomCollection versus DataTable

Standaard oplossing

Elke programmeertaal kent een favoriet objecttype dat het meest wordt gebruikt voor het transporteren en manipuleren van gegevensstructuren. In het geval van .NET is dit natuurlijk de DataTable, een bijzonder mooi mechanisme voor off-line data bewerking. Je haalt wat gegevens op, transporteert ze via de businesslaag naar de user interface, bewerkt gegevens, transporteert ze via de businesslaag terug naar de database, waar de wijzigingen vervolgens worden opgeslagen, verwijdert of gemuteerd.

 

Tijdens dit proces kom je allerlei aspecten tegen waar de DataTable standaard oplossingen voor biedt. Je wilt regelmatig via een foreach loop door de rijen itereren. Je wilt via remoting de DataTable kunnen transporteren tussen applicatieonderdelen. Misschien wil je de inhoud wel als XML behandelen. Je wilt de inhoud kunnen binden aan een user control. Je wilt kunnen ingrijpen als er inhoud is gewijzigd, en nog veel meer zaken. De DataTable biedt standaard al deze fraaie mogelijkheden.

 

Toen ik met .NET begon was ik zo enthousiast over deze mogelijkheden dat ik al gauw al mijn gegevens transport begon op te lossen met behulp van de DataTable.

Op dit moment maak ik behalve in mijn databaselaag verder helemaal geen gebruik meer van dit objecttype. Waarom niet? Twee belangrijke redenen; Type vastheid en performance.

 

Typevastheid

In principe probeer ik alles wat ik schrijf, typevast te gebruiken. Dit bespaart me veel tijd en het houdt mijn code helder, doordat ik niet op al te veel plekken hoef te casten.

 

De waardes in de DataTable zijn niet typevast. Door er een wrapper omheen te bouwen leg je al het casten op één plek. Ik heb in het begin veel zitten stoeien met een XSD file en het automatisch genereren van de DataSet classe als een soort wrapper. Erg mooi idee maar in de praktijk een hoop gedonder tijdens het compileren. Visual Studio vond het soms niet nodig om een DataSet classe opnieuw te compileren, terwijl ik wel een verandering had aangebracht in mijn XSD file.

 

Toen ik besloot de wrapper met de hand te gaan onderhouden, omdat het me veel tijd had gekost, vroeg ik me af wat het voordeel nou eigenlijk was. In iedergeval gaf het me een hoop overhead om voor elke gegevensstructuur een dergelijke class te onderhouden.

 

Performance

Veel van de voordelen die de DataTable bevat zijn niet specifiek zijn voor de DataTable zelf. De DataTable heeft simpelweg een aantal interfaces geïmplementeerd, waardoor het object deel kan nemen aan al die mooie standaard functionaliteit van het .NET Framework.

 

Het populariseren van de DataTable is een dure operatie. Dit komt omdat er allerlei zaken worden gecreëerd en geinitialiseerd die rekening houden met de mogelijke statusverandering van de gegevens. Als je hier geen gebruik van maakt, omdat je een DataTable bijvoorbeeld alleen maar gebruikt om gegevens één richting op te transporteren, betaal je hiervoor wel de prijs.

 

Een andere performance penalty is natuurlijk het feit dat de waardes die door de DataTable worden gehost, niet typevast zijn. Denk bijvoorbeeld aan het opzoeken van een waarde in een rij op basis van de kolomnaam. Onder water loopt de DataTable door de kolommen om de waarde uit de kolom met de juiste naam te retourneren. Het resultaat moet je vervolgens nog casten naar eigen gebruik.

 

Bezinning

Ik dacht nog eens goed na over de doelstelling die ik had om alles met de DataTable op te lossen. De kern daarvan was dat ik alles zo standaard mogelijk wilden houden, dat ik ooit misschien wel de gegevens via een WebService wilde ontsluiten en dat de DataTable standaard alle gegevens zo mooi naar XML serialiseert. Hierdoor zou ik software ontwikkelen die compatibel is met de rest van de wereld. Laten we eerlijk zijn: de compatibiliteit van de DataTable bestaat enkel tussen .NET applicaties. En waarom zou ik zo ingewikkeld doen als mijn gegevensstructuren enkel worden gebruikt binnen mijn eigen applicatie?

 

Als ik een gegevensstructuur heb, wil ik daarmee kunnen deelnemen aan een aantal standaard mechanismen van .NET. Hiervoor moet de gegevensstructuur voldoen aan een aantal doelstellingen.

 

Voor mij zijn de belangrijkste doelstellingen bij het gebruik van een gegevens structuur;

  • populariseren
  • itereren
  • serializeren
  • binden.

 

Als het gaat om persisteren, is dit maar een heel klein percentage van het gebruik. En het bijhouden van statusveranderingen is ook niet echt rocket science.

 

Custom collecties

Je begrijpt dat ik uiteindelijk custom collecties ben gaan gebruiken: een verademing omdat mijn code veel leesbaarder werd. Je wordt er niet blij van als je een miljoen keer de declaratie “DataTable” ziet staan. Liever declaraties als “UserCollection” en “PageTemplateCollection”.

 

Om een eigen collectie te kunnen gebruiken in een foreach loop hoef je eigenlijk alleen maar de interface “IEnumerable” te implementeren.

 

Vervolgens kun je op een heldere manier door je collectie itereren:

 

foreach(User tUser in tUserCollection)

  {

    tName   = tUser.Name;

    tAge    = tUser.Age;

    tGender = tUser.Gender;

  }

 

Als je er voor zorgt dat je gegevens via public properties te benaderen zijn, kun je ook je custom collectie standaard binden aan user controls.

 

DataGrid1.DataSource = tUserCollection;

DataGrid1.DataBind();

 

Om je eigen collectie als array te kunnen benaderen hoef je eigenlijk alleen maar een indexer te implementeren. Deze kun je dan ook direct typevast implementeren.

 

User tUser = tUserCollection[i];

 

Kortom, er ging een wereld voor me open: al die mooie mechanismen van het .NET Framework zijn te gebruiken door mijn eigen object typen. Ik moet dan wel alles zelf schrijven, maar de te implementeren interfaces zijn meestal simpel en goed gedocumenteerd.

 

Effe checken

Ik was al een half jaar bezig om de meeste zaken op te lossen middels eigen collecties. Over de werkwijze wat de code betreft, was ik heel tevreden. Maar de onzekerheid over de performance bleef knagen. Ik heb altijd verondersteld dat eigen collecties sneller zouden kunnen zijn dan DataTables, maar ik had het nog nooit gemeten. Na het bouwen van een test kan ik in ieder geval gerust adem halen: het werken met eigen collecties heeft ook op het gebied van performance zijn voordelen.

 

Bewust kiezen

Bekijk de test en zie het resultaat. Kijk kritisch en bepaal zelf of je vindt dat er appels met peren worden vergeleken. Natuurlijk blijft de DataTable voor heel veel toepassingen een waanzinnig mooi instrument, maar je moet er wel bewust voor kiezen en bepalen of je de typische features ook benut.

 



 
Geef feedback:
Verzend Commentaar