LINUXTALKS.CO

python максимально быстро заполнить список значениями.

 

L


0

0

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


Код покади. 30мегабит действительно слишком плохо даже для питухона. Не похоже на правду.

Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Holger

Ахуеть, ты совсем тугой? О_о 16 млн int это 64 млн байт. Т.е. 60 мегабайт. подели на 16 секунд - 3,75 мегабайта в секунду или 30 мегабит в секунду.

Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Anoxemian

Для сравнения, вот дохлая vps выдает:

root@moon:~# dd if=/dev/urandom of=/dev/null bs=1024 count=60024
60024+0 records in
60024+0 records out
61464576 bytes (61 MB, 59 MiB) copied, 0.386555 s, 159 MB/s

1272 мегабита. Питухон, конечно, не подарок, но не настолько.

Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Anoxemian

Многое зависит от железа, от операционки от IDE и мне не интересен пересчет на мегабайты потому что там может быть и не int кстати. Я спрашивал про оптимизацию кода и на vps тоже пофиг.
И причем тут вдруг bash?!

Holger    

Linux / Chrome (DK)
Ответ на: комментарий от Anoxemian

У python нет статической типизации потому больше памяти резервируется на хранения значений переменных и списков.

Holger    

Linux / Chrome (DK)
Ответ на: комментарий от Holger

Яннп, ты реинкарнация сугомы? Переставай тупить и показывай код, иначе это все беспредметный пиздеж.

Anoxemian    
★★★
Anonymous / Unknown (EE)
import random

def doAppend(size=16000000):
    result = []
    for i in range(size):
        message = random.randint(1, 10)
        result.append(message)
    return result

x = doAppend()
print(len(x))

out:

time ./project.py
16000000

real    0m2.849s
user    0m2.821s
sys     0m0.028s

7900X

Но это самый тупой вариант и самый медленный

serg002    
★★
Последнее исправление: serg002 (всего исправлений: 4)

Linux / Firefox (RU)
Ответ на: комментарий от serg002

Лул, можно ускориться:

#!/usr/bin/python3

import random
import time

start_time = time.time()
for x in range(1000000):
    val = int.from_bytes(random.randbytes(4))
print(time.time() - start_time)
start_time = time.time()
for x in range(1000000):
    val = random.randint(0, 2**32-1)
print(time.time() - start_time)
0.38315916061401367
0.6362998485565186
Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Anoxemian

Ну так ты же их никуда не сохранил, поэтому и быстрей. Ты же знаешь, что в зависимости от кейсов это можно сделать и гараздо быстрей и гараздо экономичней по потреблению памяти

serg002    
★★
Последнее исправление: serg002 (всего исправлений: 1)

Linux / Firefox (RU)
Ответ на: комментарий от serg002

Глядишь в книгу видишь хуй?

random.randint(0, 2**32-1)
int.from_bytes(random.randbytes(4))

две абсолютно идентичные функции работают одна в 2 раза быстрее другой. Если еще анролл добавить, еще процентов 10-20 выжать можно. Но все равно очень медленно работает.

Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Anoxemian

да насрать придерживайся контекста

Holger    

Linux / Chrome (DK)
Ответ на: комментарий от Anoxemian

да никакого уже кода не будет потому что я понял что ЛТ не для технических вопросов засрут и зафлудят все оффтопиком

Holger    

Linux / Chrome (DK)
Ответ на: комментарий от Anoxemian

по которой ты херню пишешь про какие то vps и bash что к теме не относится не будет уже никакого кода.

Holger    

Linux / Chrome (DK)
Ответ на: комментарий от Anoxemian

Добавил анролл и 4 потока, выжал максимум:

#!/usr/bin/python3

import threading
import random
import time
import gc

gc.disable()
start_time = time.time()
result = []

def fasta():
    for x in range (250000):
        bytes = random.randbytes(64)
        int_arr = []
        for i in range(0, 64, 4):
            int_arr += [int.from_bytes(bytes[i:i+4])]
        result.extend(int_arr)

threads = []
threads += [threading.Thread(target=fasta)]
threads += [threading.Thread(target=fasta)]
threads += [threading.Thread(target=fasta)]
threads += [threading.Thread(target=fasta)]

for t in threads:
    t.start()

for t in threads:
    t.join()

print(64000000/(time.time()-start_time)/1024/1024*8, "Mbps")
print(time.time()-start_time)
121.65506488408731 Mbps
4.013676881790161
Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от TheAnonymous

Вот это дает скорость эквивалентную системной. Ожидаемо, сишечка зарешала, но накладные тормоза питухона конечно завораживают.

Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Anoxemian

От обосаннлго слышу мне такие знания не нужны уёбок

Holger    

Linux / Chrome (DK)
Ответ на: комментарий от Holger

Дегенерат, я нашел у себя самый задристаный хост и он выдал результат в 40 раз быстрее твоей говнины. Предположив, что ты не на чайнике свою дрисню запускаешь, я тебе на этот факт указал. Ну каким дибилом надо быть, чтобы вместо того чтобы впитать - начать блевать. Пиздец, от этой хуйни охуеть можно. Кароч, впитывай, спасибо потом скажешь.

Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Anoxemian

так jit же не завезли, это получается все 16 миллионов каждый раз интерпретировать

TheAnonymous    
★★★★★★★★★★★
Linux / Firefox (NL)

Вообще если максимально быстро, то наверное, только numpy.

Если именно на чистом питоне, там тоже можно пооптимизировать, суть в том, чтобы не было цикла на миллионы итераций в питоновом коде (лямбда не прокатит кстати).

Например, можно взять random.choices

import random
x = random.choices(range(1, 11), k=16000000)
Если диапазон небольшой, можно развернуть range в лист random.choices(list(range(1, 11)), k=16000000), ещё немного быстрее

Ну или если пойдут значения от 0 до 255, то list(random.randbytes(16000000)) тоже быстро будет

TheAnonymous    
★★★★★★★★★★★
Последнее исправление: TheAnonymous (всего исправлений: 1)

Linux / Firefox (NL)
Ответ на: комментарий от TheAnonymous

О, ты на скиле. Просвети нам, почему такая разница у этих функций?

random.randint(0, 2**32-1)
int.from_bytes(random.randbytes(4))
Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Anoxemian

А хз, я во внутренностях питона особо не шарю. Возможно, во втором случае там сразу нативные функции, а в первом ещё какие-то проверки

TheAnonymous    
★★★★★★★★★★★
Linux / Firefox (NL)
Ответ на: комментарий от Anoxemian

Ты тут дегенерат и уебок который перепутал двач и ЛТ. Мне плевать на твои хосты пошел нахуй сразу!

Holger    

Linux / Chrome (DK)
Ответ на: комментарий от Holger

Оставайся дегенератом, хули тут.

Anoxemian    
★★★
Anonymous / Unknown (EE)

Да вы рубанулись на питухоне работать без numpy??

@TheAnonymous только адекват.

JamesHolden    
★★★★★★★★
Android / Firefox (BY)
Ответ на: комментарий от Anoxemian

Суть питухона - дернуть сишную функцию, которая сделает зашибись. Делать что-то низкоуровневое на самом пистоне, тем более дрочить байты как тут - это спецллимпиада уже.

JamesHolden    
★★★★★★★★
Android / Firefox (BY)
Ответ на: комментарий от JamesHolden

Ну интересно просто стало, я в курсе, что питухон не быстр, но вот такого я не ожидал, конечно. Сливать на порядок просто на ровном месте, это круто. А как всякие джанги и прочий миллион софта на питухоне работают? А, главное, нахуя и зачем?

Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Anoxemian

Они же байты не дрочат, там в сишные модули вынесено все что можно.

JamesHolden    
★★★★★★★★
Android / Firefox (BY)

Резюме: средствами питухона удалось добиться буста в 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    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от Anoxemian

Это все хуйня, как оказалось. В дивном питухоне есть такая штука, как 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
Anoxemian    
★★★
Anonymous / Unknown (EE)

Забавная тема.. Уже неделю молчание всех респондентов, пожалуй можно резюмировать.

От обосаннлго слышу мне такие знания не нужны уёбок

То что ты убогий писал в этом треде

Ты тут дегенерат и уебок который перепутал двач и ЛТ. Мне плевать на твои хосты пошел нахуй сразу!

Судя по всему, ТС Holger тихонечко взял именно «обоссанное» решение, что-то из последних постов Anoxemian. Но постеснялся в этом признаться и нормально закрыть свой тех.топик.

RTFM: этикет и его утилитарный смысл

ThePlayerZero    
★★
Linux / Chrome (RU)
Ответ на: комментарий от ThePlayerZero

Мы ж не на лорчике, если человеку важнее форма над содержанием - это его проблемы. А мне просто интересео было разобраться.

Anoxemian    
★★★
Anonymous / Unknown (EE)
Ответ на: комментарий от ThePlayerZero

Ты слишком культурный для нашего болота. У нас тут своя атмосфера :)

А в остальном, @Anoxemian разобрался в теме, а @Holger даже не понял насколько он не разбирается в теме, тут до признания еще как до Китая раком.

Oberstserj    
★★★★★★
Ubuntu / Firefox (NL)
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)