если значения нулевые как мне надо то вроде можно использовать range хотя я не помню уже как. а если нужно заполнить случайными значениями типа random.randint. Количество значений примерно 16 миллионов. Не спрашивайте плз зачем мне это надо. Но надо. Как оптимизировать код чтобы выполнялось максимально быстро. А то если сделать чисто append в цикле то выполняется аж ~16 секунд пиздец как много.

  • Anoxemian
    link
    fedilink
    arrow-up
    0
    ·
    1 year ago

    Резюме: средствами питухона удалось добиться буста в 300% и при этом, он все равно сливает сишечке в >10 раз. Код тракториста:

    #!/usr/bin/python3
    
    import random
    import time
    
    result = []
    start_time = time.time()
    for x in range(16000000):
        result.append(random.randint(0, 2**32-1))
    end_time = time.time()
    
    print(len(result)*4/(end_time-start_time)/1024/1024*8, "Mbps")
    print(end_time-start_time, "seconds")
    
    53.011936046379645 Mbps
    9.210779428482056 seconds
    

    Код байтоеба:

    #!/usr/bin/python3
    
    from threading import Thread
    import random
    import time
    
    result = [[],[],[],[]]
    
    def fasta(id,rnd):
        for x in range (62500):
            bytes = rnd.randbytes(256)
            int_arr = []
            for i in range(0, 256, 4):
                int_arr.append(int.from_bytes(bytes[i:i+4]))
            result[id].extend(int_arr)
    
    threads = []
    threads += [Thread(target=fasta, args=(0,random.SystemRandom(random.randbytes(16)),))]
    threads += [Thread(target=fasta, args=(1,random.SystemRandom(random.randbytes(16)),))]
    threads += [Thread(target=fasta, args=(2,random.SystemRandom(random.randbytes(16)),))]
    threads += [Thread(target=fasta, args=(3,random.SystemRandom(random.randbytes(16)),))]
    
    start_time = time.time()
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    end_time = time.time()
    
    print(16000000*4/(end_time-start_time)/1024/1024*8, "Mbps")
    print(end_time-start_time, "seconds")
    
    150.20968479876524 Mbps
    3.250664234161377 seconds
    
    • Anoxemian
      link
      fedilink
      arrow-up
      0
      ·
      1 year ago

      Это все хуйня, как оказалось. В дивном питухоне есть такая штука, как thread, ровно как и везде, но с некоторым шармом: она не работает и нихуя не распараллеливает. Ну т.е. прямо-таки существует огромный кусок питухона, тонна документации и просто море гвнокода просто так. Поржать. Это пиздец. Вот правильный параллельный код, буст относительно оригинала под 1000%, это уже сравнимо с эталоном, всего в 3-4 раза медленнее:

      #!/usr/bin/python3
      
      from multiprocessing import Process, Array
      import random
      import time
      
      result = Array('L', [0] * 16000000, lock=False)
      threads = [0] * 4;
      
      def fasta(tid,result,rnd):
          for x in range (62500):
              bytes = rnd.randbytes(256)
              idx = 0
              for n, i in enumerate(range(0, 256, 32)):
                  k = tid*4000000+x*n+idx
                  result[k]   = int.from_bytes(bytes[i:i+4])
                  result[k+1] = int.from_bytes(bytes[i+4:i+8])
                  result[k+2] = int.from_bytes(bytes[i+8:i+12])
                  result[k+3] = int.from_bytes(bytes[i+12:i+16])
                  result[k+4] = int.from_bytes(bytes[i+16:i+20])
                  result[k+5] = int.from_bytes(bytes[i+20:i+24])
                  result[k+6] = int.from_bytes(bytes[i+24:i+28])
                  result[k+7] = int.from_bytes(bytes[i+28:i+32])
                  idx += 8
      
      for tid in range(0, len(threads)):
          threads[tid] = Process(target=fasta, args=(tid,result,random.SystemRandom(random.randbytes(16))))
      
      start_time = time.time()
      for t in threads:
          t.start()
      for t in threads:
          t.join()
      end_time = time.time()
      
      period = end_time - start_time
      print(len(result)*4/period/1024/1024*8, "Mbps")
      print(period, "seconds")
      
      461.89199350374173 Mbps
      1.0571329593658447 seconds