Back to site
Since 2004, our University project has become the Internet's most widespread web hosting directory. Here we like to talk a lot about web development, networking and server security. It is, after all, our expertise. To make things better we've launched this science section with the free access to educational resources and important scientific material translated to different languages.

Dapfor .Net Grid

Dapfor .Net Grid Uvod

Deo1: Tipovi podataka
Deo2: Povezivanje podataka
Deo3: Event-driven model
Deo4: Oblikovanje podataka i prezentacija
Deo5: Bezbednost
Deo6: Obavezujuća lista bezbednosti
Deo7: Izgled i slika
Deo8: Mobilno isticanje
Deo9: Filtriranje podataka
Deo10: Sortiranje podataka
Deo11: Grupisanje podataka
Deo12: Hederi i kolone
Deo13: Editori
Deo14: Performanse. Praktične preporuke
Deo15: Real-time podsetnik
Deo16: Konvertor valuta
Deo17: Instrument pretraživač
Deo18: Naručite knjigu
Deo19: Korpa pregledača



Neto Grid Vodič part14: Performanse.Praktične preporuke

Čak i komponenta sa najboljim učinkom može biti ometena nepravilnom upotrebom.Ispod smo pružili praktične preporuke o tome šta bi trebalo da se koristi ili izbegava u aplikacijama programiranje.Prateći ispod navedene savete moći ćete da kreirate aplikacije sa istom
efikasnošću kao i ovu demo aplikaciju. Takođe nudimo izvorne kodove za ovaj primer da bi vam pokazali koliko je lako.

  • Pretpostavlja se da programeri već znaju opšte principe dizajna aplikacija.Bez obzira na to,mi ćemo dati neke korisne linkove za bolje razumevanje .Net okruženja i alatke za pisanje upravnog koda:: Brže Pisanje Upravnog Koda:Znajte koliko košta.

  • Neophodno je obratiti pažnju na mrežne karakteristike u različitim radnim režimima, radi procene volumena podataka koje će biti prikazane i da bi se našao odgovarajući grafikon za bolje razumevanje upotrebe mreže.

  • Koristite ThreadSafeBindingList umesto BindingList iz sledećih razloga:

    1.BindingList ima lošu implementaciju kada radi sa objektima koji implementiraju INotifiPropertiChanged interfej. Ovde možete naći više informacija o performansama BindingList .Koristite ThreadSafeBindingList umesto, pošto ne dozvoljava BindingList da se pretplatite na događaje objekata koji sadrži. 2.Drugi razlog za korišćenje ThreadSafeBindingList umesto BindingList se odnose na implementaciju MulticastDelegate koja se koristi u događajima. Sa jednim subscriber-om, ovaj delegat troši minimalne memorijske resurse, ali kada postoji dva ili više pretplatnika,stvara internu kolekciju pretplatnika koja dramatično povećava potrošnju memorije.Ova mreža uvek pripisuje objektima koje implementira INotifyPropertyChanged interfejs i BindingList drugom subscriber-u.

  • Ako se BindingList koristi zajedno sa objektima implementiranja INotifyPropertyChanged interfejsa, bolje je da se izbegava puštanje obaveštenja sa nepostojećim podacima objekta funkcija.To se traži retko, jer kad lista spajanja dobije takvo obaveštenje, proverava da li objekat koji se pušta ima određenu imovinu. Ako objekat koji se pušta nema takvu imovinu, BindingList generiše ListChanged događaj precizirajući Resetrazlog i prisiljava mrežu da obnovi sav svoj sadržaj

  • Izbegavajte korišćenje INotifyPropertyChanged interfejsa, sem ako je to traženo. Ako se objekat ne promeni u run-timeu, bolje je da ne koristite ovaj interfejs radi uštede memorije i CPU sredstva.

  • Dodajte podatke na kraj kolekcije (List , BindingList , ThreadSafeBindingList itd). Inače, interna implementacija indeksiranih kolekcija će se pokrenuti i ponovo indeksirati svi podatke počev od novododatog indeksa.

  • Izbegavajte dodavanje podataka u listu povezivanja sa više od 10 000 artikala, kada je mreža sortirana.Prestanite sa sortiranjem da biste poboljšali performanse. Međutim, ako želite da dodate velike količine podataka u real time-u na početak mreže,bolje je koristiti sledeće:


    grid.Sort.Enabled = false;
    grid.DataSource = _datasource_;
    //Add a single object to the beginning of the grid
    grid.Nodes.Insert(0, _new_object_);

    //Add a single object to the beginning of the binding list
    IBindingList bl = ...;
    bl.Insert(0, _new_object_);
  • Iako je mreža sigurna sa INotifyPropertyChanged i IBindingList interfejsima, koristite GUI nit za rad. Ovo je uglavnom važno za dodavanje velike količine podataka. Neki algoritmi optimizacije rade bolje kada nema potrebe da prelazite medju nitima. Takođe imajte na umu da BindingList nije sigurna nit.

  • Imajte samo jednu petlju poruka po zahtevu. Nemojte stvarati mreže na različitim nitima.

    Pretpostavimo da kompjuterski resursi nisu neograničeni.Teoretski,maksimalni učinak može biti sadržan u broj niti jednakom broju procesorskih jezgra. Dok se većina niti stvara, oni ne rade paralelno. U ovom slučaju jezgra alociraju vremenske intervale za niti na osnovu njihovog prioriteta i dosledno obavljaju zamenu kontekstu (zamena konteksta je relativno ekspanzivan rad).Imajte na umu,da je maksimalno vreme kidsnja oko 10-15 msek).

    Takođe smo uzeli u obzir da svaka kontrola slika svoj sadržaj u GDI / GDI + uređaja (preko grafičkog objekta).Dok se od jedne vrši slikanje jedne niti,sve ostale čekaju GDI uređaj za obradu slike kada dodju na red.Dakle, ako započnemo više petlja sa porukama - to ne znači da ćemo ubrzati aplikaciju. Drugim rečima, aplikacija gubi vreme na zameni konteksta i crtanju u GDI uređaju.

    Sa naše tačke gledišta aplikacija bi trebala da ima samo jednu pumpu sa porukama. Windows ima dodatne mehanizme za optimizaciju sadržaja slika i nismo sigurni da li oni rade u slučaju višenitne sredine. Naravno, poslovna logika može da rade u bilo kojoj niti, ali grafička nit treba da bude samo jednoj u aplikaciji.

  • Koristite MethodInvoker za sinhronizaciju niti.

    U višenitnim aplikacijama svaki poziv treba da bude sinhronizovan sa glavnom niti koja sadrži Windows petlju sa porukom. Obe Control.Invoke i Control.BeginInvoke metode mogu prihvatiti različite delegatne tipove i njihove parametre. Međutim, to izaziva ozbiljan problem performansi dok prizivaju Delegate.DinamicInvoke (params Object [] args), koji zauzvrat koristi odraze niskih performansi. U isto vreme, za neke učesnike, kao što EventHandler, MethodInvoker i WaitCallback se kod direktno poziva. U vreme izvršavanja koda delegat proverava pripadnost jednog od gore navedenih tipova sa određenim brojem parametara, a ako ne pripada-poziva se DinamicInvoke ().

    Sa praktične tačke gledišta proces sinhronizacije treba da izgleda na sledeći način:


    someControl.BeginInvoke(new MethodInvoker(delegate
    {
    //a code here
    }));
  • Koristite objekte proizvoljnih klasa umesto zbirki vrednosti tipa zagrada [], itd To je zgodnije i objekti proizvoljne klase troše manje memorije od zbirki niti.

  • Ne formirajte vrednosti direktno u objekte podataka, odnosno ako je vlasništvo objekat povratnog datuma, ovo polje treba da vrati DateTime tip objekta umesto tipa niza. Koristite formatiranje podatakaako je potrebno. Ako osobine vrate niti, one mogu biti pogrešno uporedjenetokom sortiranja podataka. Osim toga, upoređivanje dva niza zahteva više CPU resursa nego poređenje dva DateTime objekta.


    class DateExample
    {
    ...

    //Bad idea
    public string FormattedDate
    {
    get { return string.Format("{0:yyyy-MM-dd}", _date); }
    }

    //Good idea: the property should return non-formatted value
    [Format("yyyy-MM-dd")]
    public DateTime Date
    {
    get { return _date; }
    }
    }
  • Koristite event-driven model,ako je moguće.Na globalnom nivou to je efikasnije od potrage za redovima u jednoj ili više mreža sa dinamičkom promenom podataka.

  • Delite iste poslovne objekte u različitim mrežama. Koristite deklarativno pivezivanje.Ovo pojednostavljuje kod aplikacije i značajno smanjuje potrošnju memorije.

  • Izbegavajte korišćenje nepotrebnih omotača. Koristite deklarativno spajanje umesto stvaranja intermedijatne klase.

  • Koristite statički deklarisan EventArgs za polja podataka da bi se izbeglo stvaranje brojnih kratkotrajnih objekata tokom slanja obaveštenja putem INotifyPropertyChanged interfejsa.


    class MyDataObject : INotifyPropertyChanged
    {
    private static readonly PropertyChangedEventArgs Value1Args = new PropertyChangedEventArgs("Value1");

    private string _value1;

    public string Value1
    {
    get { return _value1; }
    set
    {
    if (_value1 != value)
    {
    _value1 = value;

    //Bad idea: short-lived object is created
    FirePropertyChanged("Value1");

    //Good idea: notify with an immutable static object
    FirePropertyChanged(Value1Args);
    }
    }
    }

    private void FirePropertyChanged(string fieldName)
    {
    if (PropertyChanged != null)
    {
    PropertyChanged(this, new PropertyChangedEventArgs(fieldName));
    }
    }

    private void FirePropertyChanged(PropertyChangedEventArgs args)
    {
    if (PropertyChanged != null)
    {
    PropertyChanged(this, args);
    }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    }
  • Radite sa objektima sa poslovnom logikom direktno, umesto pozivanja Cell.Value / Row.DataAccessor [“fieldId"] vrednosti.

    TypeDescriptor / PropertyDescriptor se koriste za prikazivanje vrednosti u ćelijama kada se radi sa proizvoljnim tipovima podataka.
    Sledeći kod pokazuje vrednost ekstraktovanja iz podataka objekata.


    MyDataObject dataObject = ...;
    dataObject.Value1 = "some value";

    PropertyDescriptor property = TypeDescriptor.GetProperties(dataObject)["Value1"];
    object value = property.GetValue(dataObject);

    Ovaj princip rada je isti za sve mreža i sve prodavace. Glavni problem je u tome što PropertyDescriptor.GetValue () metod koristi refleksiju. NetGrid ima optimizaciju koji omogućava da primate obaveštenja INotifyPropertyChanged / IBindingList bez pozivanja podataka objekta brojem glasova. Vrednosti su potrebne samo u vreme slikanja i samo za vidljive ćelije. Ako mreža ima dosta redova, većina njih su nevidljivi i ovaj pristup značajno štedi CPU resurse. Vredi,s obzirom na razvoj aplikacije. Kao primer, hajde da pregledamo pretplatu na Grid.RowUpdated događaj.


    grid.RowUpdated += delegate(object sender, GridRowUpdateEventArgs e)
    {
    //This callback is called each time when a notification from INotifyPropertyChanged received.

    //Using of custom object will reduce CPU consumption
    MyDataObject myObject = (MyDataObject) e.Row.DataObject;
    decimal lastPrice = myObject.LastPrice;

    //The following call will use the reflection. Try to avoid.
    lastPrice = (decimal) e.DataField.Value;
    };
  • Koristite novi Row.IsInVisibleBounds imovinu dodatu verziji 2.8.0

    Prilikom ažuriranja podataka u real-time u aplikacijama, mrežni prodavnice istaknu informacije za svaku ažuriranu ćeliju.Ovo podrazumevano ponašanje izaziva ozbiljnu potrošnju memorijskih resursa pored CPU resursa zbog obrade velikog obima informacija.Pošto se većina ispravki može javiti izvan vidljivog prostora, programer može da sačuva CPU resursa pomoću nove imovine.


    //Disable authomatic highlighting (from INotifyPropertyChnaged interface)
    grid.Highlighting.Enabled = false;

    //This callback is called each time when a notification from INotifyProeprtyChanged received.
    grid.RowUpdated += delegate(object sender, GridRowUpdateEventArgs e)
    {
    //Handle updates only for visible rows
    if(e.Row.IsInVisibleBounds)
    {
    //Using of custom object will reduce CPU consumption
    MyDataObject myObject = (MyDataObject)e.Row.DataObject;
    double delta = myObject.LastPrice - myObject.PrevPrice;
    if(delta != 0)
    {
    Color color = delta > 0 ? Color.Green : Color.Red;
    //highlight the 'LastPrice' cell with specified semi-transparent color for 2 seconds
    e.Row["LastPrice"].Highlight(TimeSpan.FromSeconds(2), Color.FromArgb(50, color));
    }
    }
    };

    Kada se ova optimizacija koristi, vertikalno skrolovanje može doneti redove bez ćelija sa naglašenim informacijama do vidljivog područja i korisnik neće videti naglašene ćelije koje su napravljene pre nego što redovi dodju do vidljivog dela mreže. Ovo se tiče samo istaknutih informacija, dok se tekst i sadržaj drugih ćelija prikazuje ispravno. Programer treba da odluči da li će da koristite takvu optimizaciju ili ne.

  • Dok izgradjujete hijerarhije, poželjno je da se sruše redovi korena :


    grid.RowAdded += delegate(object sender, GridRowEventArgs e)
    {
    e.Row.Expanded = false;
    };
  • Turn off fading effect when building real-time applications:


    grid.Highlighting.Fading = false;
  • Izbegavajte podešavanje boja, fontova u redovima i ćelijama zbog visoke potrošnje memorije (Boje i fontovi se čuvaju po ćeliji ili redu). Koristite Grid.Appearance / Header.Appearence svojstva i Grid.PaintRow / Grid.PaintCell rukovodioce dogadjajima:


    //The back color is stored per cell. If grid has thousands rows, memory consumption can be very high.
    Cell cell = grid.Rows[0]["Price"];
    cell.Appearance.BackColor = Color.Red;

    //The back color is stored per row. If grid has thousands rows, memory consumption can be very high.
    Row row = grid.Rows[0];
    row.Appearance.BackColor = Color.Blue;

    //Good idea: colors are stored per grid
    grid.Appearance.EvenRows.BackColor = Color.FromArgb(10, Color.Red);
    grid.Appearance.OddRows.BackColor = Color.FromArgb(10, Color.Blue);

    //Good idea: colors are stored per header (therefore per hierarchical level)
    Header header = grid.Headers[0];
    header.Appearance.EvenRows.BackColor = Color.FromArgb(10, Color.Red);
    header.Appearance.OddRows.BackColor = Color.FromArgb(10, Color.Blue);

    //Good idea: colors are specified only at painting time
    grid.PaintRow += delegate(object sender, PaintRowEventArgs e)
    {
    e.Appearance.BackColor = e.Row.VisibleIndex % 2 == 0
    ? Color.FromArgb(10, Color.Red)
    : Color.FromArgb(10, Color.Blue);
    };
  • Pokušajte da izbegavate odraze.

  • Budite veoma pažljivi pri stvaranju privremenih objekata jer to može dovesti do pritiska u memoriji i naterati da sakupljač djubreta prikuplja neiskorišćene objekte češće. Imajte na umu da kada se prikuplja smeće, sav rad aplikacija je privremeno stopiran.

  • Nemojte koristiti finalizere u objektima, osim ako je to potrebno.

Nadamo se da će vam ove jednostavne preporuke pomoći da napravite efikasne i visoko- performansne aplikacije.

 

Footer image
Published (Last edited): 19-12-2012 , source: http://www.dapfor.com/en/net-suite/net-grid/tutorial/performance-practical-recommendations