10
votes

Quelle est la vitesse de Python

Pour économiser de l'espace et la complexité de devoir maintenir la cohérence des données entre différentes sources, je envisage de stocker des indices de démarrage / fin pour certaines sous-chaînes au lieu de stocker les sous-chaînes elles-mêmes. L'astuce est que si je le fais, il est possible que je vais créer des tranches tout le temps. Est-ce quelque chose à éviter? L'opérateur de tranche est-il assez rapide, je n'ai pas besoin de vous inquiéter? Que diriez-vous de la nouvelle création d'objet / destruction des frais de création?


D'accord, j'ai appris ma leçon. Ne pas optimiser sauf s'il y a un vrai problème que vous essayez de résoudre. (Bien sûr, cela ne signifie pas non plus mal de code inutile, mais c'est à côté du point ...) Aussi, testez et profil avant de venir sur le débordement. = D Merci tout le monde!


5 commentaires

Pourquoi ne pas simplement l'essayer? Écrivez un test simple.


Je suis d'accord et j'ai voté Balpha mais je me suis toujours demandé à quelle vitesse était la tranche de python. Je l'utilise tout le temps aussi facilement qu'une simple assignation, mais je suis sûr que c'est assez lent que cela.


-1: n'a pas fait d'expérience de synchronisation.


-1: Optimisation prématurée. "assez rapide"? Assez rapide pour quoi?


Tehgeekmeister, je déteste des idées telles que ceci. Ne soyez pas intelligent. Pourtant, c'est presque ce que Java fait avec des sous-chaînes.


5 Réponses :


8
votes
  1. assez rapide par opposition à quoi? Comment faites-vous cela maintenant? Qu'est-ce que vous stockez exactement, qu'est-ce que vous récupérez exactement? La réponse dépend probablement de cela. Ce qui nous amène à ...

  2. mesure! Ne discutez pas et analysez théoriquement; Essayez de mesurer quelle est la manière la plus performante. Ensuite, décidez si le gain de performance possible justifie de refactoriser votre base de données.

    EDIT: Je viens de courir une chaîne de mesure de test Thingings Versus Recherche dans une dicte touchée sur (début, fin) tuples. Cela suggère qu'il n'y a pas beaucoup de différence. C'est un joli test naïf, cependant, alors prenez-le avec une pincée de sel.


3 commentaires

La méthode actuelle stocke simplement un texte, des phrases et des jetons dans la phrase toutes comme des chaînes distinctes (dans la base de données) et reliant chacune de l'autre. On dirait beaucoup de blagine inutile pour moi; Un texte de 2 Mo finit par prendre 28 Mo de base de données. Quoi qu'il en soit, qu'est-ce qui serait récupéré tout le temps est des phrases individuelles du texte. L'alternative coupe le texte en fonction des indices stockés. Mais tu as un très bon point. La mesure est probablement la meilleure façon d'y aller. = P


Ne sous-estimez pas également la pièce de décision: s'il existe un compromis de performance / de stockage (et la plupart du temps, vous devez prendre en compte les ressources que vous avez. 28 Mo n'est pas beaucoup si vous avez vraiment besoin de l'heure du processeur, mais vous avez un disque dur des téraoctets à votre disposition. 28 Mo est Beaucoup si vous exécutez un petit système intégré qui ne peut être consulté qu'une fois par jour. Eh bien, je suppose que tout ce que je viens d'écrire se résume à "ça dépend toujours" :-)


@tehgeekMeister: Veuillez mettre à jour votre question avec ces faits supplémentaires.



-2
votes

L'optimisation prématurée est le rôle de tout mal.

Prouvez-vous à vous que vous avez vraiment besoin d'optimiser le code, puis d'agir.


0 commentaires

1
votes

Je n'ai pas fait de mesures non plus, mais comme cela ressemble, vous prenez déjà une approche C dans un problème dans Python, vous voudrez peut-être jeter un coup d'œil à Python MMAP bibliothèque :

Les objets de fichier mappés de mémoire se comportent comme des chaînes et des objets de fichier similaires. Contrairement aux objets de chaîne normaux, cependant, ceux-ci sont mutables. Vous pouvez utiliser des objets MMAP dans la plupart des endroits où des cordes sont attendues; Par exemple, vous pouvez utiliser le module RE à rechercher dans un fichier mappé de mémoire. Comme ils sont mutables, vous pouvez changer un seul caractère en faisant obj [index] = 'a' ou modifier une sous-chaîne en attribuant une tranche: Obj [I1: I2] = "...". Vous pouvez également lire et écrire des données à partir de la position du fichier actuel et recherchez () via le fichier à différentes positions.

Je ne suis pas sûr de votre question si c'est exactement ce que vous recherchez. Et il est répété que vous devez prendre des mesures. Python's Timeit bibliothèque est facile à utiliser, mais Il y a aussi CProfile ou hotshot , bien que hotshot risque d'être retiré de la bibliothèque standard comme je le comprends.


0 commentaires

3
votes

Dans un commentaire, l'OP mentionne BLOAT "dans la base de données" - mais aucune information sur la base de données dont il parle; Depuis les informations de SAFANT dans ce commentaire, il semblerait que les tranches de cordes Python ne soient pas nécessairement ce qui est impliqué, plutôt que la "tranchage" serait effectuée par le moteur de la DB lors de la récupération.

Si c'est la situation réelle, je recommanderais des principes généraux contre la conservation des informations redondantes dans la DB - une "forme normale" (peut-être dans un sens laxiste de l'expression ;-) dans laquelle les informations sont stockées une fois et des informations dérivées est recalculé (ou charge mise en cache du moteur de base de données, etc.-) devrait être la norme et la "dénormalisation" en stockant délibérément des informations dérivées très bien l'exception et uniquement lorsque cela est justifié par des besoins spécifiques de performance de récupération bien mesurés.

Si la référence à la "base de données" était une mauvaise administration ;-), ou plutôt utilisée dans un sens laxiste comme je l'ai fait pour "forme normale" ci-dessus ;-), une autre considération peut s'appliquer: car les cordes Python sont immuables, Il semblerait être naturel de ne pas avoir à faire des tranches en copiant, mais plutôt à chaque tranche de réutiliser une partie de l'espace mémoire du parent, il est en train de trancher (beaucoup comme pour les tranches de tableaux numpy). Cependant, cela ne fait actuellement pas partie du noyau Python. Je l'ai fait une fois essayé un patch à cette fin, mais le problème de l'ajout d'une référence à la grande chaîne et de le rendant ainsi de la mémoire en mémoire simplement parce qu'une minuscule sous-chaîne de celle-ci est toujours référencée à grande vitesse pour l'adaptation générale. Il serait toujours possible de faire une sous-classe de chaîne (et d'unicode) à des fins spéciales pour le cas dans lequel la grande chaîne «parent» doit rester en mémoire de toute façon. Actuellement, tampon fait un petit morceau de cela, mais vous ne pouvez pas appeler des méthodes de chaîne sur un objet tampon (sans la copier explicitement à un objet de chaîne en premier), il n'est donc que vraiment utile pour la sortie et quelques-unes Des cas spéciaux ... mais il n'y a pas de véritable bloc conceptuel contre l'ajout de méthode de chaîne (je doute que cela soit adopté dans le noyau, mais il devrait être décemment facile à maintenir en tant que module tiers de toute façon; -).

La valeur d'une telle approche peut difficilement être solidement prouvée par la mesure, d'une manière ou d'une autre, une vitesse serait très similaire à l'approche actuelle de copie implicite; L'avantage viendrait entièrement en termes de réduction de l'empreinte mémoire, ce qui ne rendrait pas tellement de code Python donné plus rapidement, mais permettrait plutôt d'exécuter un certain programme d'exécuter sur une machine avec un peu moins de RAM, ni multi-tâche mieux lorsque plusieurs instances sont utilisés en même temps dans des processus distincts. Voir Rope pour une approche similaire mais plus riche expérimentée dans le contexte de C ++ (Mais noter que cela ne l'a pas fait dans la norme; -).


0 commentaires

1
votes

Les tranches seraient inefficaces car elles créent des copies de la chaîne source? Cela peut être ou non être un problème. S'il s'avère être un problème, ne serait-il pas possible de simplement implémenter une "vue à la chaîne"; Un objet qui a une référence à la chaîne source et a un point de départ et de fin. Après accès / itération, il suffit de lire à partir de la chaîne source.


1 commentaires

C'était mon inquiétude. Mais je pense que tout le monde avait raison: je n'ai pas encore besoin d'optimiser, et si je le faisais, j'aurais dû mesurer et testé avant de venir ici.