9
votes

Python ajoute la performance

J'ai des problèmes de performance avec "APPEND" en Python. J'écris un algorithme qui vérifie s'il y a deux cercles qui se chevauchent dans un (grand) ensemble de cercles. Je commence en mettant les points extrêmes des cercles (x_i-r_i & x_i + r_i) dans une liste, puis trier la liste.

list.append(foo)


4 commentaires

Liste n'est pas un bon nom de variable dans Python.


Liste n'est jamais un bon nom de variable dans une langue ...


"" "" Liter des chaînes "" "" ne sont pas # Commentaires . Et Docstrings doit aller à l'intérieur de la fonction, pas avant la fonction.


@eumiro, CrazyJugglerdrummer: Vrai, changé en Cirkelist à la place. @Sven: Non utilisé à la manière Python de commenter les choses, je garderai votre avis à l'esprit.


5 Réponses :


14
votes

au lieu de xxx

utiliser xxx

ceci pourrait diminuer votre O (n ^ 2) à O (n).

Votre ensemble makelist pourrait être écrit comme suit: xxx


6 commentaires

@Harm C'est un bon conseil - vous devriez également envisager d'utiliser une drique pour cela (voir Module de collections) car il aurait légèrement une meilleure performance pour les opérations d'append. Vous pouvez alors vouloir le convertir en une liste à la fin, afin que les économies ne puissent pas l'emporter sur les frais généraux.


Ah Ok, je regardais la mauvaise chose tout le temps .. Merci pour la réponse :) Soin pour expliquer pourquoi l'index d'un cercle est-il (n²)? O (n) Je comprendrais depuis que l'indice d'un objet dans une liste est égal à la recherche de la liste jusqu'à ce que vous trouviez cet objet.


@Harm: La recherche linéaire se fait dans chacune des n itérations de la boucle pour la boucle, donnant un total de O (n * n).


@Harm: un seul .index () est O (n), mais le faisant pour chaque élément de la liste le fait O (n ^ 2).


@ Sven, Eumiro: Goddamnit, je fais vraiment attention, suis-je? TSSS. Une dernière question, qu'est-ce que l'opérateur mathématique aime-t-il exactement la somme tout en faisant la liste? Pourriez-vous expliquer ce qui se passe dans cette ligne de code?


Il a une mauvaise utilisation somme pour concaténer beaucoup de listes - Somme ([x, y, z] par défaut) est est par défaut + x + y + z . A une performance assez sous-optimale à la manière - elle crée d'abord une grande liste en mémoire, puis fait n Time O (n) concaténation avec eux. Un meilleur one-liner serait (élément pour i, encercler en énumérant (cercles) pour l'élément dans ([Cercle.m [0] -circle.r, 0, I], [Cercle.m [0] + cercle.r, 1, i]) qui évite d'avoir toutes les données en mémoire avant de construire la liste et construit la liste des résultats entière à la fois sans concats.



7
votes

Votre problème de performance n'est pas dans la méthode APPEND () , mais dans votre utilisation de cercles.index () , ce qui rend le tout O (n ^ 2 ).

Une amélioration supplémentaire (comparative mineure) consiste à utiliser une compréhension de la liste au lieu de list.append () : xxx

Notez que Cela donnera aux données dans un ordre différent (qui ne devrait pas avoir d'importance car vous envisagez de le trier de toute façon).


1 commentaires

Je suis tout à fait nouveau à Python et j'apprends toujours des choses python-esquées comme des compréhensions de la liste. Merci d'avoir répondu :)



1
votes

Si la performance était un problème, j'éviterais d'utiliser Ajout. Au lieu de cela, prévenez un tableau puis remplissez-le. J'éviterais également d'utiliser l'index pour trouver la position dans la liste des "cercles". Voici une réécriture. Ce n'est pas compact, mais je parierai que c'est rapide à cause de la boucle déroulée. xxx


0 commentaires

3
votes

Je viens d'essayer plusieurs tests pour améliorer la vitesse de "append". Cela vous aidera certainement à vous. Strong>

  1. Utiliser Python Li>
  2. Utilisation de la liste (carte (Lambda - connue sous le nom de moyens plus rapides que pour + Ajouter Li>
  3. Utiliser Cyron Li>
  4. Utilisation de numba - JIT LI> OL>

    Code Contenu: Obtenir des numéros de 0 ~ 9999999, carez-les et mettez-les dans une nouvelle liste à l'aide de l'annexe. H1>
    1. utilisant python p>

      import timeit
      from numba import jit
      
      st1 = timeit.default_timer()
      
      @jit(nopython=True, cache=True)
      def f1():
      
          a = range(0, 10000000)
      
          result = []
          append = result.append
      
          for i in a:
              append( i**2 )
      
          return result
      
      f1()
      
      st2 = timeit.default_timer()
      print("RUN TIME : {0}".format(st2-st1))
      


0 commentaires

2
votes

Essayez d'utiliser DEQUE dans le paquet de collections à ajouter Grandes rangées de données, sans performance diminuant. Puis convertissez une drique à un dataframe en utilisant compréhension de la liste . < p> cas d'exemples: xxx

Il s'agit d'un épargnant en temps réel.


0 commentaires