2016-04-03 3 views
1

dans js je dois trier beaucoup d'éléments de tableau (100k-1kk). Dans la production son possible d'avoir beaucoup blank ('') chaînes.gérer les chaînes vides à array.sort (?) Callback dans chrome est très lent

dans ma fonction de tri i gérer des valeurs vides - de sorte que ces valeurs viennent toujours en dernier .Son ok .. jusqu'à ce que je ai beaucoup nulle ou non définie ou vide (« ») valeurs dans les données

si les données ont de nombreux zéros par exemple ou des chaînes vides, les performances sont très lentes.

Et la chose principale est que ce fragment très lent à Chrome (au moins pour l'instant dernière version 49.0.2623.110 m)

Firefox (45.0.1) fonctionne très bien (même avec Standart cas sans données vides mon test x10 plus rapide ??) juste test.with chrome et firefox

PS Je sais que jsperf est plus préférable pour that.anyway

https://jsfiddle.net/3h0gtLu2/18/

data = [] 

var i = 0; 

while (i++ <1000){ 

    data.push('' + i) 
} 

while (i++ < 20000){ 

    data.push(''+i ) 

} 

var start = window.performance.now() 
data.sort(function(a,b){ 

    if (a == null || a == undefined) 
         return 1; 
    else if (b == null || b == undefined) 
         return -1; 
    return (parseInt(a) - parseInt(b)); 
}) 

$('#time0').html($('#time0').html() + (window.performance.now() - start)) 


data = [] 

var i = 0; 

while (i++ <1000){ 

    data.push('' + i) 
} 

while (i++ < 20000){ 

    data.push(null ) 

} 

var start = window.performance.now() 
data.sort(function(a,b){ 

    if (a == '' || a === null || a == undefined) 
         return 1; 
    else if (a == '' || b === null || b == undefined) 
         return -1; 
    return (parseInt(a) - parseInt(b)); 
}) 


$('#time1').html($('#time1').html() + (window.performance.now() - start)) 


data = [] 

var i = 0; 

while (i++ <1000){ 

    data.push('' + i) 
} 

while (i++ < 20000){ 

    data.push('' ) 

} 

var start = window.performance.now() 
data.sort(function(a,b){ 

    if (a == null || a == undefined) 
         return 1; 
    else if (b == null || b == undefined) 
         return -1; 
    return (parseInt(a) - parseInt(b)); 
}) 

$('#time2').html($('#time2').html() +(window.performance.now() - start)) 

data = [] 

var i = 0; 

while (i++ <1000){ 

    data.push('' + i) 
} 

while (i++ < 20000){ 

    data.push('' ) 

} 

var start = window.performance.now() 
data.sort(function(a,b){ 

    if (a == '' || a == null || a == undefined) 
         return 1; 
    else if (b == '' || b == null || b == undefined) 
         return -1; 
    return (parseInt(a) - parseInt(b)); 
}) 
$('#time3').html($('#time3').html() +(window.performance.now() - start)) 
+2

Si vous ne postez pas le code, il est peu probable que quelqu'un puisse vous aider. – Pointy

+0

code désolé posté :) –

+0

Le problème est que votre fonction de comparaison de tri est incohérente, et cela peut rendre l'algorithme de tri devenir fou. Pour les deux mêmes valeurs, votre comparateur doit toujours retourner exactement la même réponse. – Pointy

Répondre

1

Afin de vous assurer que votre comparateur renvoie toujours une réponse logique pour chaque paire de valeurs, vous devrez ajouter le cas pour lorsque les deux valeurs sont vides:

data.sort(function(a,b){ 
    var anull = (a == '' || a == null), bnull = (b == '' || b == null); 
    if (anull && bnull) 
    return 0; 
    if (anull) 
    return 1; 
    if (bnull) 
    return -1; 
    return (parseInt(a) - parseInt(b)); 
}) 

Notez que vous n'avez pas besoin explicite comparer à la fois null et undefined; comparer == null est exactement le même que de comparer === null et === undefined. Je m'assure de dire à l'algorithme de tri que lorsque les deux valeurs sont vides, elles peuvent être laissées à elles-mêmes (en retournant 0), vous éviterez ainsi de faire des va-et-vient dans certains cas bizarres. Une autre chose qui pourrait accélérer les choses serait de faire un seul passage dans le tableau pour convertir toutes les entrées vides en une seule valeur (peut-être null, peu importe) et toutes les entrées non-vides aux nombres réels . De cette façon, votre tri ne paiera pas le prix de la conversion des chaînes à des numéros encore et encore (c'est-à-dire, tous les appels à parseInt()). Si vous voulez que le tableau soit des chaînes, vous pouvez toujours le convertir en un seul passage ultérieur.

+0

merci beaucoup. –