Les chaînes de Python sont immuables et prennent en charge l'interface tampon. Il pourrait être efficace de ne pas renvoyer les nouvelles chaînes, mais les mémoires tampons pointant vers les parties de l'ancienne chaîne lors de l'utilisation de tranches ou de la méthode True: Dans des situations régulières, les frais de mémoire sont linéaires et ne sont pas perceptibles. La copie est rapide, et c'est ainsi l'allocation. Mais il y a déjà trop fait à Python, alors peut-être que de tels tampons valent la peine d'effort? P>
EDIT: P>
Il semble que former des sous-chaînes de cette manière rendrait la gestion de la mémoire beaucoup plus compliquée. Le cas où seulement 20% de la chaîne arbitraire est utilisé et que nous ne pouvons pas annuler le reste de la chaîne, est un exemple simple. Nous pouvons améliorer l'allocator de la mémoire. Il serait donc en mesure de réexaminer les chaînes partiellement, mais ce serait probablement surtout un reprovement. Toutes les fonctions standard peuvent toute façon être émulée avec .split () code>. Cependant, un nouvel objet de chaîne est construit à chaque fois. Pourquoi? La seule raison pour laquelle je vois, c'est qu'il peut faire un peu plus difficile la collecte des ordures. P>
tampon code> ou MemoryView code> si la mémoire devient critique. Le code ne serait pas si concis, mais il faut abandonner quelque chose afin d'obtenir quelque chose. P>
3 Réponses :
C'est à quel point les tranches fonctionnent. Des tranches effectuent toujours une copie peu profonde, vous permettant de faire des choses comme maintenant, il serait possible de faire une exception pour les chaînes, mais cela en vaut vraiment la peine? Eric Lippert a blogué sur sa décision ne pas faire cela pour .NET ; Je suppose que son argument est valable pour Python. P> Voir aussi Cette question . P > p>
Oui, c'est très utile lors de l'itération de l'objet mutable, par exemple. Mais ici, pour les cordes? Cela ne violerait pas la cohérence.
@HAROLD: vrai, mais peut-être que cela ne vaut pas l'effort. J'ai édité ma réponse.
Il semble que Eric essayait d'optimiser sérieusement, même pour des concaténations. La classe StringBuilder vifient donc vraiment le besoin de telles optimisations complexes dans C #.
Si vous êtes inquiet de la mémoire (dans le cas de très grandes chaînes), utilisez un tampon connaissant à ce sujet vous permet d'alternatives à des méthodes de chaîne telles que Si vous souhaitez ou, en utilisant () code>: Split () code>. p> Split () code> une chaîne, mais gardez l'objet de chaîne d'origine (comme vous pouvez peut-être besoin de), vous pouvez faire: p> .index () code>: p>
Oui, je sais sur les tampons. Mais que si je veux utiliser la méthode Split () sur la chaîne arbitraire?
@HAROLD Vous pouvez "imiter" cela répondant à vos besoins, voir mon édition. OTOH, si vous divisez une chaîne et n'en avez plus besoin, vous pouvez déposer l'original, libérer la mémoire et avoir sur la même empreinte mémoire que possible.
La représentation de chaîne sous-jacente est permettant de se référer aux sous-chaînes de Une chaîne signifie compliquer beaucoup em> la collecte des ordures et la manipulation des chaînes. Pour chaque chaîne, vous devez suivre la piste combien d'objets se réfèrent à chaque caractère ou à chaque gamme d'indices. Cela signifie compliquer beaucoup le Ajoutez le fait que commencer avec Python3 Strings a 3 représentations internes différentes, et les choses vont être trop salissantes pour être maintenables,
Et votre proposition ne donne probablement que suffisamment d'avantages à être acceptés. P> Un autre problème avec ce type d'optimisation est lorsque vous souhaitez annoncer "grandes chaînes": p> < Pré> xxx pré> Après cette opération, vous avez la sous-chaîne 99% des délais que les chaînes utilisées dans les programmes sont des "petits" (caractères maximum 10k), la copie de la part est donc vraiment rapide, tandis que les optimisations que vous proposez commencent à devenir efficaces avec de très grandes chaînes (par exemple, prenez des sous-chaînes de taille 100k d'énormes les textes)
et sont beaucoup plus lents avec de très petites chaînes, ce qui est le cas commun, c'est-à-dire que le cas qui devrait être optimisé. p> Si vous pensez être important, vous êtes libre de proposer un PEP, montrer une implémentation et Les changements résultants de l'utilisation de la vitesse / de la mémoire de votre proposition. Si cela vaut vraiment la peine d'être effort, il peut être inclus dans une future version de Python. P> P> struct code> d'objets de chaîne et toute opération qui les traite, c'est-à-dire a, probablement grand, ralentissement. P>
B code> qui empêche a code>, une énorme chaîne, à traiter. Vous pouvez sûrement faire des copies de petites chaînes, mais si b = a [: 10000] code> (ou un autre grand nombre)? 10000 caractères ressemblent à une grande chaîne qui devrait utiliser l'optimisation pour éviter de copier, mais il empêche de réaliser des mégaoctets de données.
Le collectionneur des ordures devrait continuer à vérifier s'il vaut la peine de rétrograder un gros objet de chaîne et de faire des copies ou non, et toutes ces opérations doivent être aussi rapides que possible, sinon vous finirez de diminuer les performances de temps. P>
Je ne pense pas que la proposition de l'OP est une bonne idée, mais pour des raisons différentes ("ne tirez pas le message"). Le premier paragraphe est intéressant et certainement un problème de puner à CPPHON, mais ce n'est pas un problème fondamental et ce ne serait pas la première fois que la représentation des chaînes change considérablement. Le deuxième paragraphe suppose une mise en œuvre stupide. Vous pouvez simplement avoir la sous-chaîne voir l'objet de chaîne approprié et stocker un démarrage et une longueur / extrémité (et cette représentation ignore parfaitement les tripes de l'objet de chaîne, le troisième paragraphe disparaît donc dans une bouffée de logique).
La phrase sur le style de représentation désignée est assez cognée. Mais c'est intéressant: ce style est-il utile du tout? Pour les fonctions telles que Strcpy, peut-être, mais ils peuvent être modifiés avec des fonctions telles que Strncpy ...
@HAROLD Je ne pense pas que ce soit pour Strcpy code>, car la longueur est disponible, il est plus simple et plus rapide de simplement memcpy code> - de même pour d'autres fonctions standard. Il est probablement d'éviter une copie lors de la transformation d'une chaîne C pour un code tiers / client (voir pybytes_asstring code> et similaire).
Comment retourneriez-vous des parties d'une chaîne? Vous voulez dire des pointeurs? Qu'advient-il de la chaîne enfant si la chaîne d'origine est supprimée?
Qu'est-ce qui devient au tampon, si l'objet d'origine est supprimé? Je pense que la collection des ordures est suffisamment intelligente et ne supprime pas l'objet d'origine.
Je crois que votre question est un duplicatin de Si des chaînes sont immuables dans .NET, alors pourquoi la sous-chaîne prend-elle O (n) heure? . Les mêmes arguments sont valables pour Python.