Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Encore le comportement de l'interprêteur

4 réponses
Avatar
Pierre Maurette
Bonsoir,

Vous avez sans doute remarqué que j'ai un peu de mal à me faire à
l'idée d'un interprêteur. J'ai déjà posté à propos de ces angoisses
existentielles. Voici celle du jour, que j'ai en arrière pensée depuis
longtemps, et pour laquelle je voudrais lever le doute. J'ai la forme
normale:

dummi = line.split(':')
if len(dummi) == 2 and \
dummi[0].strip().lower() == betzonedeb and\
len(dummi[1].strip()) != 0:
myvar = dummi[1].strip()

Bon, l'exemple est caricatural, cette forme est convenable. Mais si
j'écris:

if len(line.split(':')) == 2 and \
line.split(':')[0].strip().lower() == betzonedeb and\
len(line.split(':')[1].strip()) != 0:
myvar = line.split(':')[1].strip()

voire, sur une seule "ligne":

myvar = (lambda: None, lambda: line.split(':')[1].strip())\
[len(line.split(':')) == 2 and \
line.split(':')[0].strip().lower() == betzonedeb and\
len(line.split(':')[1].strip()) != 0]()

est-ce que split(':') sera appelée plusieurs fois ?

Merci de vos lumières, et bonne soirée...

--
Pierre Maurette

4 réponses

Avatar
jeanfrancoisbombeeck
On 14 mar, 20:03, Pierre Maurette wrote:
Bonsoir,

Vous avez sans doute remarqué que j'ai un peu de mal à me faire à
l'idée d'un interprêteur. J'ai déjà posté à propos de ces ango isses
existentielles. Voici celle du jour, que j'ai en arrière pensée depuis
longtemps, et pour laquelle je voudrais lever le doute. J'ai la forme
normale:

dummi = line.split(':')
if len(dummi) == 2 and
dummi[0].strip().lower() == betzonedeb and
len(dummi[1].strip()) != 0:
myvar = dummi[1].strip()

Bon, l'exemple est caricatural, cette forme est convenable. Mais si
j'écris:

if len(line.split(':')) == 2 and
line.split(':')[0].strip().lower() == betzonedeb and
len(line.split(':')[1].strip()) != 0:
myvar = line.split(':')[1].strip()

voire, sur une seule "ligne":

myvar = (lambda: None, lambda: line.split(':')[1].strip())
[len(line.split(':')) == 2 and
line.split(':')[0].strip().lower() == betzonedeb and
len(line.split(':')[1].strip()) != 0]()

est-ce que split(':') sera appelée plusieurs fois ?

Merci de vos lumières, et bonne soirée...

--
Pierre Maurette


Mes réponses en vrac:
- je ne comprend pas en quoi tes questions portent sur le fait que le
langage soit interprété.
- pourquoi veux-tu savoir si split(':') est appelé plusieurs fois ?
("premature optimization is the root of all evil"). Si la nature de
tes données et du probléme te permettent d'affirmer que line ne
changera pas (c'est le cas ici) , pour des tas de bonnes raisons
(lisibilité entre autre), il vaut mieux le calculer une fois pour
toutes. Sinon pas. De toutes façons même si il est appelé plusieurs
fois, il peut y avoir un cache dans la fonction donc c'est le genre de
questions qu'il faut se poser en fin de développement __SI__ IL Y A UN
PROBLEME DE PERFORMANCE AVERE
- sur ce genre de traitement, tu peux utiliser re (ce n'est pas de
l'optimisation mais une manière adéquate d'exprimer les contraintes):
ll=lambda betzonedeb, la_chaine: re.match('^s*%ss*:s*([^:s]+)s*$'
% betzonedeb, la_chaine)
mo=ll((betzonedeb, la_chaine)
my_var=mo.group(1) if mo else none #exemple se basant sur le tien et
non testé

Petite remarque: si tu avais posté "du code qui marche" (ce qui est
conseillé), j'aurais pu faire pareil (sans faire des tas
d'hypotheses).

Voilà, j'espére que ça t'éclaire ;-)

Avatar
Bruno Desthuilliers
Bonsoir,

Vous avez sans doute remarqué que j'ai un peu de mal à me faire à l'idée
d'un interprêteur. J'ai déjà posté à propos de ces angoisses
existentielles. Voici celle du jour, que j'ai en arrière pensée depuis
longtemps, et pour laquelle je voudrais lever le doute. J'ai la forme
normale:

dummi = line.split(':')
if len(dummi) == 2 and
dummi[0].strip().lower() == betzonedeb and
len(dummi[1].strip()) != 0:
myvar = dummi[1].strip()

Bon, l'exemple est caricatural, cette forme est convenable. Mais si
j'écris:

if len(line.split(':')) == 2 and
line.split(':')[0].strip().lower() == betzonedeb and
len(line.split(':')[1].strip()) != 0:
myvar = line.split(':')[1].strip()

voire, sur une seule "ligne":

myvar = (lambda: None, lambda: line.split(':')[1].strip())
[len(line.split(':')) == 2 and
line.split(':')[0].strip().lower() == betzonedeb and
len(line.split(':')[1].strip()) != 0]()

est-ce que split(':') sera appelée plusieurs fois ?


autant de fois que tu l'appelle. Il n'y a aucune optimisation de ce côté là.

Pour ma part, je l'écrirais:

dummi = [item.strip() for item in line.split(':')]
if len(dummi) == 2
and dummi[0].lower() == betzonedeb
and dummi[1]:
myvar = dummi[1]




Merci de vos lumières, et bonne soirée...



Avatar
Bruno Desthuilliers
On 14 mar, 20:03, Pierre Maurette wrote:
Bonsoir,

Vous avez sans doute remarqué que j'ai un peu de mal à me faire à
l'idée d'un interprêteur. J'ai déjà posté à propos de ces angoisses
existentielles. Voici celle du jour, que j'ai en arrière pensée depuis
longtemps, et pour laquelle je voudrais lever le doute. J'ai la forme
normale:

dummi = line.split(':')
if len(dummi) == 2 and
dummi[0].strip().lower() == betzonedeb and
len(dummi[1].strip()) != 0:
myvar = dummi[1].strip()

Bon, l'exemple est caricatural, cette forme est convenable. Mais si
j'écris:

if len(line.split(':')) == 2 and
line.split(':')[0].strip().lower() == betzonedeb and
len(line.split(':')[1].strip()) != 0:
myvar = line.split(':')[1].strip()

voire, sur une seule "ligne":

myvar = (lambda: None, lambda: line.split(':')[1].strip())
[len(line.split(':')) == 2 and
line.split(':')[0].strip().lower() == betzonedeb and
len(line.split(':')[1].strip()) != 0]()

est-ce que split(':') sera appelée plusieurs fois ?

Merci de vos lumières, et bonne soirée...

--
Pierre Maurette


Mes réponses en vrac:
- je ne comprend pas en quoi tes questions portent sur le fait que le
langage soit interprété.


Je pense que Pierre a l'habitude de langages plus statiques, où le
compilo peut se permettre pas mal d'optimisations. Mais effectivement,
c'est plus en rapport avec l'aspect très dynamique de Python qu'avec la
distinction compilation/interprétation, puisque les JVM récentes savent
effectuer des optimisations de ce genre.

- pourquoi veux-tu savoir si split(':') est appelé plusieurs fois ?
("premature optimization is the root of all evil").


Il y a une différence entre "optimisation prématurée" et "code
manifestement inepte". Se soucier du coût moyen de certaines opérations
courantes n'est pas une optimisation prématurée, mais du simple bon sens.

En l'occurrence, deux des opérations courantes les plus coûteuses en
Python sont la résolution d'attributs, particulièrement sur les
attributs calculés (ce qui est le cas des méthodes) et l'appel de
fonction (encore plus pour les méthodes, puisqu'il y a en fait deux
appels, le premier à la méthode, le second à la fonction qui implémente
la méthode).

Si la nature de
tes données et du probléme te permettent d'affirmer que line ne
changera pas (c'est le cas ici) , pour des tas de bonnes raisons
(lisibilité entre autre), il vaut mieux le calculer une fois pour
toutes.


+1

Sinon pas.


Dans l'exemple ci-dessus, il semble peu probable que line change durant
l'opération (en partant du principe que line est une chaine, donc
immutable...)

De toutes façons même si il est appelé plusieurs
fois, il peut y avoir un cache dans la fonction donc c'est le genre de
questions qu'il faut se poser en fin de développement __SI__ IL Y A UN
PROBLEME DE PERFORMANCE AVERE


Mmm... Crois moi, je ne suis pas un acharné de l'optimisation. Pourtant,
là, c'est quand même le genre de trucs dont j'aurais tendance à me
soucier un minimum. Parce que si tu a 50 kloc de code écrit comme ça (je
veux dire: avec des appels de fonctions redondants à toutr de bras), tu
aura certainement des problèmes de perfs et pas mal de travail pour
remettre ça en l'état.

Accessoirement, au dela des 'éventuels' problèmes de perf, il y a une
autre - bonne - raison de préférer la solution 1 à la 3 : la lisibilité !-)

(snip)


Avatar
Pierre Maurette

[...]

autant de fois que tu l'appelle. Il n'y a aucune optimisation de ce côté là.


Merci beaucoup. Dont acte...

Pour ma part, je l'écrirais:

dummi = [item.strip() for item in line.split(':')]
if len(dummi) == 2
and dummi[0].lower() == betzonedeb
and dummi[1]:
myvar = dummi[1]


Oui. J'avais fait ça (dummi -> s pour ligne plus courte):

s = [item.strip() for item in line.split(':')]
if len(s) == 2 and s[0].lower() == betzonedeb and s[1]:
myvar = s[1]


--
Pierre Maurette