DTS, .NET e le prestazioni

Nella vita di un programmatore bisogna avere poche certezze.


Ho un DTS particolarmente lento. In realtà deve trasferire una gran mole di dati, ma il tempo complessivo di elaborazione risulta piuttosto lungo. Bene, mi sono detto, anche se DTS è veloce si può fare di meglio, magari scrivendo un programma ad-hoc. Inoltre il DTS richiede una manutenzione piuttosto corposa anche se deve solo trasferire delle tabelle senza fare troppe trasformazioni (anche se qualche trasformazione VBScript in mezzo la si trova), quindi un programma molto specializzato per questo tipo di attività poteva avere senso.


Dopo aver analizzato tutte le possibilità di accedere alla fonte dati (ODBC e driver nativi) e alla destinazione (interfaccia BCP e SqlProvider) mi sono messo al lavoro. Il risultato prestazionale è stato un miglioramento veramente marginale rispetto a quanto già faceva DTS, ma la manutenzione è ora più semplice e quindi almeno un risultato è stato raggiunto. Però ci sono molte lezioni da trarre.



  1. DTS è veloce; non sottovalutare mai le prestazioni di DTS, anche se bisogna conoscerlo a fondo per trarne il massimo

  2. .NET è veloce, fino a che tratta dati managed

  3. Quando arrivano delle stringhe ANSI (8bit) come nel caso di un driver ODBC o nativo, in .NET qualsiasi cosa facciate prima di tutto la stringa passa in UNICODE (come stringa managed)… per poi magari tornare a essere ANSI se la sua destinazione è un VARCHAR. Tutto ciò ha un prezzo, ed è un prezzo molto molto alto se l’applicazione fa solo copia di stringhe o quasi

  4. Il problema del marshaling è, da un punto di vista prestazionale, molto pesante. Un aspetto non secondario probabilmente lo gioca anche il fatto di essere multithread, con allocazioni prevalentemente dinamiche. Con un profiler si scoprono cose bizzarre, come per esempio il costo esorbitante di lstrlen usata per verificare la lunghezza di una stringa ANSI prima di convertirla in stringa managed.

  5. DTS di SQL 2005 è tutto managed… saprà fare di meglio? DTS di SQL 2000 va molto veloce perché riduce le conversioni al minimo. Potenzialmente in .NET il problema del marshaling è sempre alle porte.

  6. In .NET per le prestazioni a volte bisogna commettere dei piccoli delitti: leggere dei campi privati, chiamare direttamente funzioni ODBC bypassando la classe managed, fare un po’ di “spaghetti-code” per evitare il boxing, tanto elegante quanto costoso.

Ok, non sto suggerendo di abbandonare .NET, sto solo testimoniando che in casi neanche troppo estremi è necessario scendere a qualche compromesso di troppo. In un mondo 100% managed tutto questo sparirà, ma ci vorrà ancora qualche anno.