Performance en ce qui concerne le type de retour pour la requête LINQ compatible avec tri automatique

StackOverflow https://stackoverflow.com/questions/1761597

Question

ce n'est pas vraiment un problème, mais plus d'une préoccupation que je vous serais reconnaissant de certains commentaires sur s'il vous plaît.

WinForms C # .net3.5 [sp1] Visual Studio 2008 en utilisant Linq2Sql (plus précisément PLINQO ... ce qui est fantastique BTW!). Je un jeu de résultats du scrutin +/- 19000 lignes de données (avec environ 80bytes de données par ligne) et opté pour pousser le procédé de récupération de données à l'arrière-plan et mettre à jour l'interface utilisateur en conséquence. Cela fonctionne très bien.

Cependant, je l'ai remarqué quelques différences de performances lors de l'utilisation de différents types de retour ma méthode de récupération de données Ling. Je sais que tout le monde suggère un retour List<T> ou IEnumarable<T>, et définir la source de données du DataGridView à cela, mais malheureusement, il ne supporte pas nativement le tri des objets. Après quelques recherches, j'ai trouvé autour de la SortableBindingList<T> sur MSDN . Je l'ai appliqué, et la grille pris en une seconde pour se remplir -. Mais quand je clique sur une colonne pour trier, il a fallu un peu plus d'une seconde ou à mettre en œuvre le genre

Je décide alors d'aller la route DataTable, mais a constaté que la méthode ToDataTable a été supprimé, mais après plus de creuser trouvé un moyen de mettre en œuvre sur cette MSDN article . Après son application, j'ai découvert que la récupération a pris environ 2 secondes pour remplir la grille, mais le tri par la suite (sur 19000 lignes!) Était instantanée !! Bien sûr, je coincé avec cette approche.

Gardez à l'esprit que j'ai désactivé tout en grille d'édition / ajout / suppression. La grille est purement pour afficher des données. Toutes les autres opérations CRUD sont fournis par les formes de dialogue en fonction de la ligne courante sélectionnée (colonne de clé primaire masqué).

Voici le code je pour les deux méthodes:

1) SortableBindingList

    //declare private member
    private SortableBindingList<PdtAllocation> listAlloc = null;

    private void RefreshData() {
        bcsDataContext ctx = new bcsDataContext();
        try {
            listAlloc = new SortableBindingList<PdtAllocation>(ctx.PdtAllocation.ToList());
        }
        catch (Exception) {
            throw;
        }
        finally {
            ctx.Dispose();
        }

        dataGridView1.DataSource = listAlloc;
    }

2) CopyToDataTable

    //declare private member
    private DataTable dt = null;

    private void RefreshData() {
        dt = new DataTable();
        bcsDataContext ctx = new bcsDataContext();
        try {
            ctx.PdtAllocation.CopyToDataTable(dt, LoadOption.PreserveChanges);
        }
        catch (Exception) {
            throw;
        }
        finally {
            ctx.Dispose();
        }

        dataGridView1.DataSource = dt;
    }

Maintenant, je sais que cela semble probablement comme un « a demandé et reçu une réponse » cas, mais je voudrais vraiment apprécier votre entrée, ainsi que des problèmes connus avec aller la route CopyToDataTable().

Merci u .... et excuses pour la requête looong!

Était-ce utile?

La solution

voici mon avis sur votre question (aller la route SortableBindingList).

Avez-vous utilisé un algorithme de tri générique, basé réflexion? Je l'ai fait au début et la performance était vraiment mauvais. Enfin, je suis venu avec la solution suivante: fournir le tri par défaut dans SortableBindingList<T> mais aussi laisser ouverte la possibilité de mettre en œuvre le tri spécialisé dans les classes dérivées

.

Voici un code.

En SortableBindingList<T>.ApplySortCore():

protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
    // Check if the sorted property implements IComparable
    ...

    List<T> itemsList = (List<T>)this.Items;

    Comparison<T> comparer = GetComparer(prop);

    itemsList.Sort(comparer);

    if (direction == ListSortDirection.Descending)
    {
        itemsList.Reverse();
    }

    ...
    // Set sort state (is sorted, sort property, sort dir)
}

Le SortableBindingList<T> générique fournit une base, trieuse à base de réflexion:

protected virtual Comparison<T> GetComparer(PropertyDescriptor prop)
{
    return new Comparison<T>(delegate(T x, T y)
    {
        if (prop.GetValue(x) != null)
            return ((IComparable)prop.GetValue(x)).CompareTo(prop.GetValue(y));
        else if (prop.GetValue(y) != null)
            return -1 * ((IComparable)prop.GetValue(y)).CompareTo(prop.GetValue(x));
        else
            return 0;
    });
}

Comme vous pouvez le voir, GetComparer() est virtuel, donc on peut le remplacer dans une classe dérivée de SortableBindingList<T> afin de fournir une beaucoup comparateur plus rapide, peaufiné au type de la propriété étant effectivement triés. Par exemple, alors que le comparateur générique trié (par une propriété String) 10000 enregistrements en 4 secondes, le comparateur spécialisé a fait le même travail en 70ms.

class CustomerList : SortableBindingList<Customer>
{
    protected override Comparison<Customer> GetComparer(PropertyDescriptor prop)
    {
        Comparison<Customer> comparer = null;
        switch (prop.Name)
        {
            case "FirstName":
                comparer = new Comparison<Customer>(delegate(Customer x, Customer y)
                {
                    string xx = (null == x) ? null : x.FirstName;
                    string yy = (null == y) ? null : y.FirstName;
                    return String.Compare(xx, yy);
                });
                break;
            ...
        }
        return comparer;
    }
}

Une note finale: grande partie du code affiché a été copié / inspiré d'autres sources, comme SO ou Microsoft, de sorte que le crédit est pas à moi. Ma seule contribution a été virtualiser le comparateur mais je suis sûr un peu googler serait meilleure surface, des solutions antérieures fondées sur la même idée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top