title: My Automated Python script loses so much performance over time
body: <p>This is my code, i know its long and messy code, but basically. At start its pretty fast and stuff, but after while you can notice really huge performance jumps, after 6 hours, i came back. and one click of keyboard button took like 10 seconds, can anybody help me find why is it slowing so much.
  If you dont understand the code because i know its very messy and no comments. Its basically while loop that runs arround pressings buttons, and when it encounters pokemon, it reads its name and if its the one i want, it notifies me. Or if it errors, it notifies me too.
  If i dont want it, it kills it</p>
  <pre class="lang-py prettyprint-override"><code>            while active:
  
                  gc.collect()
                  gc.collect()
                  gc.collect()
  
                  time.sleep(0.1)
  
  
                  def waitclick():
                      while True:
                          if keyboard.read_key() == &quot;f6&quot;:
                              global active
                              active = False
  
                  thread = threading.Thread(target=waitclick).start()
  
  
  
                  im = numpy.asarray(pyautogui.screenshot(region=hpcheck))
  
  
                  # Define the blue colour we want to find - remember OpenCV uses BGR ordering
                  color = [175, 65, 63]
                  X, Y = numpy.where(numpy.all(im == color, axis=2))
                  x = list(X)
                  if lenght:
                      cnt = 0
                      if len(x) &lt;= lenght * (3 / 4):
                          while len(x) &lt;= lenght* (5 / 6):
                              if cnt &gt; 20:
                                  pyautogui.click(2119, 793)
                                  pyautogui.keyDown('4')
                                  time.sleep(0.01)
                                  pyautogui.keyUp('4')
                                  pyautogui.click(2050, 1120)
                                  pyautogui.click(1720, 1030)
  
                                  break
                              cnt += 1
                              time.sleep(1)
                              pyautogui.moveTo(potion[0],potion[1], random.uniform(0.5,1))
                              pyautogui.click(potion[0],potion[1])
                              time.sleep(0.01)
                              pyautogui.click(potion[0],potion[1])
                              time.sleep(0.1)
                              pyautogui.moveTo(mainpoke[0],mainpoke[1],random.uniform(0.5,1))
                              pyautogui.click(mainpoke[0],mainpoke[1])
                              pyautogui.click(mainpoke[0], mainpoke[1])
                              im = Image.fromarray(im)
                              im.save(&quot;health.png&quot;)
                              im.close()
  
  
                              im = numpy.asarray(pyautogui.screenshot(region=(hpcheck)))
                              # Define the blue colour we want to find - remember OpenCV uses BGR ordering
                              color = [175, 65, 63]
                              X, Y = numpy.where(numpy.all(im == color, axis=2))
                              x = list(X)
  
  
                          lenght = len(x)
                  else:
                      lenght = len(x)
  
  
  
  
  
                  key = keys[0] if steps % 2 == 0 else keys[1]
                  pyautogui.keyDown(key)
                  pixels = []
                  battle = False
                  timeup = False
  
  
  
  
                  def wait():
                      global stepsleft
                      global steps
                      global battle
                      counter = 0
                      for i in range(stepsleft):
  
                          if battle:
                              break
                          counter += 1
                          time.sleep(onetile-(random.uniform(0.001,0.002)))
                      stepsleft = stepsleft - counter
                      if stepsleft == 0:
                          steps += 1
                          stepsleft = tiles
                      global timeup
                      timeup = True
  
  
  
  
  
                  thread = threading.Thread(target=wait).start()
  
                  while True:
  
                      if timeup:
  
                          break
                      im = numpy.asarray(pyautogui.screenshot(region=(check)))
                      if list(im[0, 0]) == [230, 230, 230]:
                          battle = True
  
                          break
  
  
  
  
  
                  pyautogui.keyUp(key)
                  stepcount += 1
  
  
                  im = numpy.asarray(pyautogui.screenshot(region=(check)))
  
                  # im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
  
                  if stepcount &gt; 15:
                      if fails &gt; 100:
                          call = client.calls.create(twiml='&lt;Response&gt;&lt;Say&gt;Ahoy, World!&lt;/Say&gt;&lt;/Response&gt;',
                                                     to='+421949847318', from_='+18596961895')
                          payload = {
  
                              &quot;content&quot;: f&quot;Step Fail, continuing.&quot;
                          }
  
                          r = requests.post(f&quot;https://discord.com/api/v9/channels/{channel_id}/messages&quot;,
                                            data=payload,
                                            headers=header)
                          gc.collect()
                          fails = 0
                          stepfails += 1
                          if stepfails &gt; 10:
                              break
                      pyautogui.click(2119, 793)
                      pyautogui.keyDown('4')
                      time.sleep(0.01)
                      pyautogui.keyUp('4')
                      pyautogui.click(2050,1120)
                      pyautogui.click(1720, 1030)
  
                      time.sleep(1)
                      fails += 1
                  if battle == True:
                      breaks += 1
                      stepcount = 0
                      c = 0
                      e = False
                      while True:
                          if c &gt; 600:
                              e = True
                              break
                          else:
                              im = numpy.asarray(pyautogui.screenshot(region=(namecheck)))
  
                              if list(im[0, 0]) == [254, 254, 254]:
  
                                  break
                              c += 1
  
                      if e:
                          pyautogui.keyDown('4')
                          time.sleep(0.01)
                          pyautogui.keyUp('4')
                          pyautogui.click(2050, 1120)
                          time.sleep(1)
  
  
                      else:
                          encounters += 1
                          im = numpy.asarray(pyautogui.screenshot(region=(mon)))
                          im = cv2.resize(im, None, fx=1.2, fy=1.2, interpolation=cv2.INTER_CUBIC)
                          im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
  
                          kernel = numpy.ones((1, 1), numpy.uint8)
  
                          im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
                          im = cv2.dilate(im, kernel, iterations=1)
                          im = cv2.erode(im, kernel, iterations=1)
                          im = ~im
                          text = pytesseract.image_to_string(im)
  
                          text = text.strip().replace(&quot;\n&quot;,&quot;&quot;)
  
  
                          ime = Image.fromarray(im)
                          ime.save(f&quot;Wild {text}.png&quot;)
                          ime.close()
  
                          if text == &quot;&quot;:
                              ime = Image.fromarray(im)
                              ime.save(&quot;fail.png&quot;)
                              ime.close()
                              im = numpy.asarray(pyautogui.screenshot(region=(mon)))
                              im = cv2.resize(im, None, fx=1.6, fy=1.6, interpolation=cv2.INTER_CUBIC)
                              im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
  
                              kernel = numpy.ones((1, 1), numpy.uint8)
  
                              im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255,
                                                 cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
                              im = cv2.dilate(im, kernel, iterations=1)
                              im = cv2.erode(im, kernel, iterations=1)
                              im = ~im
                              text = pytesseract.image_to_string(im).strip()
  
                              print(&quot;&gt;&quot; + text + &quot;&lt;&quot;)
                              if text == &quot;&quot;:
                                  ime = Image.fromarray(im)
                                  ime.save(&quot;fail2.png&quot;)
                                  ime.close()
                                  im = numpy.asarray(pyautogui.screenshot(region=mon))
                                  print(&quot;&gt;&quot; + text + &quot;&lt;&quot;)
                                  im = cv2.resize(im, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
                                  im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
  
                                  kernel = numpy.ones((1, 1), numpy.uint8)
  
                                  im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255,
                                                     cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
                                  im = cv2.dilate(im, kernel, iterations=1)
                                  im = cv2.erode(im, kernel, iterations=1)
                                  im = ~im
                                  text = pytesseract.image_to_string(im).strip()
                                  if text == &quot;&quot;:
  
                                      im = numpy.asarray(pyautogui.screenshot(region=check))
                                      if list(im[0, 0]) != [230, 230, 230]:
                                          pass
                                      else:
                                          Image.fromarray(im)
                                          ime.save(&quot;fail3.png&quot;)
  
                                          ime.close()
                                          print(&quot;&gt;&quot; + text + &quot;&lt;&quot;)
                                          payload = {
  
                                              &quot;content&quot;: f&quot;Go look at this bro, i failed again.&quot;
                                          }
  
                                          r = requests.post(f&quot;https://discord.com/api/v9/channels/{channel_id}/messages&quot;, data=payload,
                                                            headers=header)
                                          active = False
                                          call = client.calls.create(twiml='&lt;Response&gt;&lt;Say&gt;Ahoy, World!&lt;/Say&gt;&lt;/Response&gt;',
                                                                     to='+421949847318', from_='+18596961895')
                                          gc.collect()
  
  
                                          break
                          if text.replace(&quot;[S]&quot;,&quot;&quot;).replace(&quot;[E]&quot;,&quot;&quot;).replace(&quot;\n&quot;,&quot;&quot;) not in pokemonlist:
                              ime = Image.fromarray(im)
                              ime.save(&quot;fail.png&quot;)
                              ime.close()
                              im = numpy.asarray(pyautogui.screenshot(region=mon))
  
                              im = cv2.resize(im, None, fx=1.6, fy=1.6, interpolation=cv2.INTER_CUBIC)
                              im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
  
                              kernel = numpy.ones((1, 1), numpy.uint8)
  
                              im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255,
                                                 cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
  
  
                              im = cv2.dilate(im, kernel, iterations=1)
                              im = cv2.erode(im, kernel, iterations=1)
                              im = ~im
                              text = pytesseract.image_to_string(im).strip().replace(&quot;\n&quot;,&quot;&quot;)
                              print(&quot;&gt;&quot; + text + &quot;&lt;&quot;)
                              if text.replace(&quot;[S]&quot;,&quot;&quot;).replace(&quot;\n&quot;,&quot;&quot;).replace(&quot;[E]&quot;,&quot;&quot;) not in pokemonlist:
                                  ime = Image.fromarray(im)
                                  ime.save(&quot;fail2.png&quot;)
                                  ime.close()
                                  im = numpy.asarray(pyautogui.screenshot(region=mon))
                                  im = cv2.resize(im, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
                                  im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
  
                                  kernel = numpy.ones((1, 1), numpy.uint8)
  
                                  im = cv2.threshold(cv2.bilateralFilter(im, 5, 75, 75), 0, 255,
                                                     cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
                                  im = cv2.dilate(im, kernel, iterations=1)
                                  im = cv2.erode(im, kernel, iterations=1)
                                  im = ~im
                                  text = pytesseract.image_to_string(im).strip()
                                  print(&quot;&gt;&quot; + text + &quot;&lt;&quot;)
                                  if text.replace(&quot;[S]&quot;,&quot;&quot;).replace(&quot;\n&quot;,&quot;&quot;).replace(&quot;[E]&quot;,&quot;&quot;) not in pokemonlist:
                                      ime = Image.fromarray(im)
                                      ime.save(&quot;fail3.png&quot;)
                                      ime.close()
                                      print(&quot;&gt;&quot; + text + &quot;&lt;&quot;)
                                      payload = {
  
                                          &quot;content&quot;: f&quot;Go look at this bro, i failed again.&quot;
                                      }
  
                                      r = requests.post(f&quot;https://discord.com/api/v9/channels/{channel_id}/messages&quot;, data=payload,
                                                        headers=header)
                                      active = False
                                      call = client.calls.create(twiml='&lt;Response&gt;&lt;Say&gt;Ahoy, World!&lt;/Say&gt;&lt;/Response&gt;',
                                                                 to='+421949847318', from_='+18596961895')
                                      gc.collect()
  
  
                                      break
                          encounter_time = datetime.datetime.utcnow()
                          times.append(encounter_time)
  
                          if not ram or encounters &lt; 5:
                              ram = process.memory_info().rss
                          if encounters &lt; 15:
                              recentspeed = &quot;None yet&quot;
                          else:
                              recentspeed = str(round(
                                  (15 / (encounter_time - times[encounters - 15]).total_seconds()) * 60, 2)) + &quot;/min&quot;
                          print(
                              f&quot;Pokemon: {text} #{encounters}\nSpeed: {round((encounters / (encounter_time - start).total_seconds()) * 60, 2)}/min \nRecent Speed: {recentspeed}\nRam usage is {process.memory_info().rss} Starting usage was {process.memory_info().rss-ram} Garbage is {gc.get_count()}&quot;)
  
                          payload = {
                              &quot;content&quot;: f&quot;{'-'*20}\nPokemon: {text} #{encounters}\nSpeed: {round((encounters / (encounter_time - start).total_seconds()) * 60, 2)}/min \nRecent Speed: {recentspeed}\n Ram Change: `{(process.memory_info().rss-ram)//1000000}MB`\nRam usage: `{process.memory_info().rss//1000000}MB`\nStarting usage: `{ram//1000000}MB`\nGarbage: {gc.get_count()}\nCPU: {psutil.cpu_percent()}&quot;
                          }
  
                          r = requests.post(f&quot;https://discord.com/api/v9/channels/{logs_id}/messages&quot;, data=payload,
                                            headers=header)
                          gc.collect()
  
                          #json
                          with open(&quot;encounters.json&quot;, &quot;r&quot;) as a_file:
                              json_object = json.load(a_file)
                          a_file.close()
                          try:
                              json_object[text] += 1
                          except:
                              json_object[text] = 1
                          with open(&quot;encounters.json&quot;, &quot;w&quot;) as a_file:
                              json.dump(json_object, a_file)
                          a_file.close()
                          c = 0
                          e = False
                          while True:
                              if c &gt; 500:
                                  pyautogui.click(2119, 793)
                                  pyautogui.keyDown('4')
                                  time.sleep(0.01)
                                  pyautogui.keyUp('4')
                                  pyautogui.click(2050, 1120)
                                  pyautogui.click(1720, 1030)
                                  time.sleep(1)
                                  e = True
                                  break
                              im = numpy.asarray(pyautogui.screenshot(region=battlecheck))
                              if list(im[0, 0]) == [240, 211, 92]:
                                  break
                              c += 1
                          if e == True:
                              continue
                          if (text.startswith(&quot;[S]&quot;) if shinies else text.replace(&quot;[E]&quot;,&quot;&quot;) in shinywanted) or text.replace(&quot;[S]&quot;,&quot;&quot;).replace(&quot;[E]&quot;,&quot;&quot;) in wanted:
                              time.sleep(2)
                              end = datetime.datetime.utcnow()
                              done = end - start
                              timed = humanize.naturaldelta(done)
  
                              print(&quot;Done! in &quot; + timed)
  
  
  
                              im = numpy.asarray(pyautogui.screenshot(region=win))
                              ime = Image.fromarray(im)
                              ime.save(f&quot;{text}.png&quot;)
                              ime.close()
  
  
  
                              # File
                              files = {
                                  &quot;file&quot;: (f&quot;{text}.png&quot;, open(f&quot;{text}.png&quot;, 'rb'))
                                  # The picture that we want to send in binary
                              }
                              # Optional message to send with the picture
                              payload = {
                                  &quot;content&quot;: f&quot;Found {text} in {timed} of searching. It took {encounters} encounters&quot;
                              }
                              active = False
                              r = requests.post(f&quot;https://discord.com/api/v9/channels/{channel_id}/messages&quot;, data=payload,
                                                headers=header, files=files)
                              gc.collect()
                              call = client.calls.create(twiml='&lt;Response&gt;&lt;Say&gt;Ahoy, World!&lt;/Say&gt;&lt;/Response&gt;',to='+421949847318',from_='+18596961895')
                              time.sleep(25)
                              if remote:
                                  pyautogui.click(3804, 15)
  
                              break
  
                              playsound('ringtone.mp3')
  
                          elif text.startswith(&quot;[E]&quot;) or text.replace(&quot;[S]&quot;,&quot;&quot;).replace(&quot;[E]&quot;,&quot;&quot;) in avoid:
                              run()
                              c = 0
                              while True:
                                  if c &gt; 300:
                                      pyautogui.click(2119, 793)
                                      pyautogui.click(1720, 1030)
                                      pyautogui.keyDown('4')
                                      time.sleep(0.01)
                                      pyautogui.keyUp('4')
                                      pyautogui.click(2050, 1120)
                                      time.sleep(1)
                                      break
                                  else:
  
                                      im = numpy.asarray(pyautogui.screenshot(region=check))
                                      if list(im[0, 0]) != [230, 230, 230]:
  
                                          break
                                      c += 1
                          else:
                              #time.sleep(random.randint(50, 70) / 100)
                              kill(text.replace(&quot;[S]&quot;,&quot;&quot;).replace(&quot;[E]&quot;,&quot;&quot;))
  
                              c = 0
                              time.sleep(1)
                              while True:
                                  if c &gt; 750:
                                      pyautogui.click(2119, 793)
                                      pyautogui.click(1720, 1030)
                                      pyautogui.keyDown('4')
                                      time.sleep(0.01)
                                      pyautogui.keyUp('4')
                                      pyautogui.click(2050, 1120)
                                      time.sleep(1)
                                      break
                                  else:
  
                                      im = numpy.asarray(pyautogui.screenshot(region=check))
                                      if list(im[0, 0]) != [230, 230, 230]:
                                          break
                                      c += 1
  </code></pre>