7
votes

Optimiser le code JavaScript qui masse les noms de propriétés JSON

Je travaille sur une application Web qui reçoit des données JSON avec des noms de propriété majuscules. J'ai besoin que ces noms de propriété soient minuscules, donc j'utilise une fonction pour boucler de manière récursive via l'objet JSON et les convertir en minuscules.

Le problème est que mes réponses JSON peuvent devenir très grandes. Je veux que la fonction fonctionne bien même si elle doit traiter JSON avec 60 000 noms de propriétés et différents niveaux d'imbrication.

La fonction de masse inférieure est la suivante: xxx

Et j'effectue une analyse comparative ici: http://jsfiddle.net/emw89/7/

Les horloges de test ci-dessus à environ 570ms sur ma machine.

Y a-t-il quelque chose que je puisse faire pour améliorer la performance de cette fonction?

EDIT: i fermé mon IE, rouvert à nouveau, c'est-à-dire la référence Jsfiddle à nouveau - il arrive maintenant à ~ 180ms pour moi. Mon IE avait été ouvert pendant quelques jours tout droit jusqu'à juste à ce moment-là, alors peut-être que c'est ce qui causait une telle performance. De toute façon, je suis toujours intéressé s'il y a un moyen d'optimiser cette fonction plus loin. Chaque fois que le temps passé à traiter JSON ait directement ajouté au temps écoulé de chaque demande Ajax.


5 commentaires

il complète environ 150 ms pour moi


78ms - IE9. Hourra pour i7 cpu. Chrome semble environ 30% plus lentement. Toutes les dépenses sont dans la récursion, donc je ne suis pas sûr qu'il y ait beaucoup d'autre que cela peut être fait.


Deux mots: chrome cadre


Pourriez-vous donner un peu plus de contexte? Pourquoi avez-vous besoin d'eux en minuscules? Vous ne pouvez pas réparer la source du JSON?


Je viens de fermer / rouvrir mon point d'accès et le temps de traitement tombé de ~ 570ms à ~ 180ms. Peut-être que c'est-à-dire que c'est-à-dire ouvert pendant une longue période peut ralentir la performance ... qui sait? @Tim La raison pour laquelle j'ai besoin de cette fonction est parce que je tire des données d'un étrange backend exclusif. Ce backend sérialise des données de structure d'enregistrement dans JSON avec tous les noms de propriété capitalisés - aucun moyen autour de celui-ci. L'alternative à cette fonction est de capitaliser toutes les propriétés de mon code ainsi que des modèles côté client - mais cela devient très rapide.


3 Réponses :


5
votes
var lowerCache = {};

FN = function (obj)
{
    if (typeof(obj) === "string" || typeof(obj) === "number")
        return obj;

        var l = obj.length;
    if (l) {
        l |= 0;
        var result = [];
        result.length = l;
        for (var i = 0; i < l; i++) {
            var newVal = obj[i];
            result[i] = typeof(newVal) === "string" ? newVal : FN(newVal);
        }
        return result;
    } else {
     var ret = {};
     for (var key in obj) {

         var keyStr = typeof(key) === "string" ? key : String(key);
         var newKey = lowerCache[keyStr];
         if (newKey === undefined) {
             newKey = keyStr.toLowerCase();
             lowerCache[keyStr] = newKey;
         }

         var newVal = obj[key];
         ret[newKey] = typeof(newVal) === "string" ? newVal : FN(newVal);
     }
     return ret;
    }
};
100% faster.

11 commentaires

hm ... si obj est matrimonie, ce code retourne un tableau vide ou je me trompe


Cela ressemble au gagnant, mais je vais laisser la question sans réponse pendant un peu plus longtemps au cas où un autre magicien propose quelque chose.


Fait quelques bugs. Toujours beaucoup plus vite.


Pouvez-vous dire un peu de quelles données vous attendez? Les données auront-elles les mêmes valeurs de clé souvent? La structure est-elle régulière?


Il y a un peu de cruft ici: 1) Qu'est-ce que var a trucs dans la première ligne? 2) vous pouvez ajouter || obj.push au premier si instruction. 3) typeof (clé) === "chaîne" sera toujours vrai; Toutes les clés des objets JavaScript sont des chaînes (même dans les tableaux).


1) vrai. C'est un travail en cours ;-) 2) Non, car nous devons marcher récursivement dans des valeurs de tableau 3) NO: Alerte (typeof ([1] [0]));


Les données auront souvent les mêmes valeurs de clé. Ce que vous voyez dans mon exemple JSFIDDLE JSON est très proche de ce que je traiterai réellement. Il pourrait y avoir des cas où le JSON a 3-4 niveaux d'imbrication.


La première version a oublié de descendre récursivement dans les valeurs de tableau.


BTS La plupart des objets ont seulement cinq valeurs clés distinctes. Est-ce destiné?


Ce n'est pas prévu - il suffit de se faire paresseux de taper des valeurs clés distinctes. Les valeurs essentielles sur les objets seront toutes uniques - mais elles finiront par se répéter dans les tableaux / la nidification.


Publié une nouvelle version qui cause des résultats de tolower.



3
votes

Je le ferais avec la simple réégalité de remplacement.

  1. Utilisez JSON pour convertir un objet en chaîne li>
  2. Remplacez toutes les propriétés avec le même nom juste minuscule li>
  3. Convertissez à nouveau une chaîne en objet li> ol>

    E.g. P>

    var obj = { SENAD: "meskin" };
    
    var str = JSON.stringify(obj);
    
    function lCase(xxx)
    {
        pattern = /\"([a-z0-9_-]{0,})\"\:/gi;
        return  xxx.replace(pattern, function() { return arguments[0].toLowerCase() });
    }
    str = lCase(str);
    
    var newObj = JSON.parse(str);
    alert(newObj.senad);
    console.log(str);
    


1 commentaires

+1 En fonction de la complexité du JSON, je pense que cela pourrait être préférable. JSON est déjà une chaîne, vous devriez donc être capable de sauter l'étape 1 (qui est l'avantage sur l'autre méthode).



1
votes

Si vous traitez de gros objets JSON avec IE (ou tout autre navigateur - mais c'est-à-dire que c'est plus susceptible de cracher le mannequin) Je vous recommande de traiter votre json / matrice dans des morceaux.

Une bonne explication de ce processus peut être trouvée ici http://oreilly.com/server-administration /excerpt/even-faster-websites/writing-efficient-javascript.html (faites défiler les "motifs de la minuterie pour produire" en-tête)


0 commentaires