LINUX.ORG.RU

Чтобы скрипт быстрее

 , чудокод


1

2
import random
with open("file1", "ab") as f1:
    for x in range(2000000):
        f1.write(bytes([random.randint(0,255)]))

Подскажите пути повышения производительности, но без платформозависимых /dev/urandom и нестандартных библиотек

★★★★★

Последнее исправление: af5 (всего исправлений: 2)

Ты не тот язык для задачи такой выбрал. Если тебе нужна производительность возьми C и т.д. P.S. можешь написать расширение на C для Python и использовать его.

deterok ★★★★★
()
Ответ на: комментарий от deterok

Ты тоже. Ему просто надо перестать индусской хернёй страдать.

Goury ★★★★★
()

1) Если Python 2 - используй xrange 2) Формируй большой буфер в памяти и большими блоками пиши в файл - это точно поможет, любой язык тормозит если побайтно писать в файл

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft
import random
import time
start_time = time.time()

with open("file1", "ab") as f1:
    for x in range(200000):
        f1.write(bytes([random.randint(0,255)]))
    t1 = time.time()
print("dt1=" + str(t1-start_time))

with open("file2", "ab") as f1:
    m1=[]
    for x in range(200000):
        m1.append(random.randint(0,255))
    f1.write(bytes(m1))
    t2 = time.time()
print("dt2=" + str(t2-t1))

with open("file3", "ab", 1000) as f1:
    m2=[]
    for x in range(200000):
        m2.append(random.randint(0,255))
    f1.write(bytes(m2))
    t3 = time.time()
print("dt3=" + str(t3-t2))

with open("file4", "ab", 100000) as f1:
    m3=[]
    for x in range(200000):
        m3.append(random.randint(0,255))
    f1.write(bytes(m3))
    t4 = time.time()
print("dt4=" + str(t4-t3))
dt1=1.1515777111053467
dt2=0.9134173393249512
dt3=0.6354153156280518
dt4=0.6305148601531982
af5 ★★★★★
() автор топика
Последнее исправление: af5 (всего исправлений: 1)
Ответ на: комментарий от af5

append не очень быстро... надо нечто, что выделит память сразу «под всё» и ты просто кладешь в элементы свои значения

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от af5
with open("file5", "ab", 100000) as f5:
    m4 = [random.randint(0, 255) for _ in range(200_000)]
    f5.write(bytes(m4))
    t5 = time.time()
print("dt5=" + str(t5-t4))

# Короче, но немного медленнее
with open("file6", "ab", 100000) as f6:
    f6.write(bytes(random.randint(0, 255) for _ in range(200_000)))
    t6 = time.time()
print("dt6=" + str(t6-t5))
dt1=0.5840334892272949
dt2=0.4480257034301758
dt3=0.46602630615234375
dt4=0.4580264091491699
dt5=0.41802382469177246
dt6=0.42702436447143555
Esper
()
Ответ на: комментарий от Esper

Как вариант

import numpy
import random
import time

def write(path, mode, size):
    with open(path, mode) as file:
        file.write( (numpy.random(size) * 255).astype(numpy.int32).tobytes() )

start_time = time.time()
write("file1", "ab", 20000)
t1 = time.time()
print("dt1=" + str(t1-start_time))

write("file2", "ab", 20000)
t2 = time.time()
print("dt2=" + str(t2-t1))

write("file3", "ab", 1000)
t3 = time.time()
print("dt3=" + str(t3-t2))

write("file4", "ab", 200000)
t4 = time.time()
print("dt4=" + str(t4-t3))

alex4321
()
Ответ на: комментарий от alex4321

А, хотя - нестандартная библиотека же. Тогда я бы заморочился буфером (array, возможно?), записью наших рандомов в него (а не добавлением элементов) и, возможно - буферизацией вывода.

alex4321
()
Ответ на: комментарий от alex4321

в моём numpy нет numpy.random(size)
точно код правильный? и да, numpy просто ради теста, но надо без него

af5 ★★★★★
() автор топика

Подскажите пути повышения производительности, но без платформозависимых /dev/urandom и нестандартных библиотек

Очевидно же. Go.

anonymous
()
Ответ на: комментарий от af5

в моём numpy нет numpy.random(size)

with open('file7', 'ab') as f7:
    f7.write(numpy.random.randint(256, size=200_000, dtype='uint8').tobytes())
t7 = time.time()
print(f'dt7={t7-t6}')

На два порядка быстрее, однако.

Esper
()
Ответ на: комментарий от af5

Вот подмывало дать пример с numpy, надеюсь numpy достаточно стандартная библиотека? :) Оно кстати скорее всего внутрях создает сразу большой массив и заполняет, и небось на Си.

I-Love-Microsoft ★★★★★
()

Если 3.6, то secrets.token_bytes, иначе os.urandom

anonymous
()
Ответ на: комментарий от af5

А, собственно, настолько ли это большая проблема? Подтянуть numpy как зависимость хоть pip-м, хоть (для линухов) apt/rpm - не должно быть проблемой, в репах он таки есть же. Так что если планируется много числодробления - я таки серьёзно задумался бы о numpy

alex4321
()
Ответ на: комментарий от af5

положить в проект, вырвать нужный кусок и положить в проект

anonymous
()
Ответ на: комментарий от alex4321

Да не нужны там ни платформа ни дистрибутив, юзеру просто надо быстро создать десяток рандомных файлов заданного размера и всё на этом. Скрипт был бы вариантом, а «дистрибутив» это уже перебор

af5 ★★★★★
() автор топика
Ответ на: комментарий от Esper

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

af5 ★★★★★
() автор топика
Ответ на: комментарий от af5

Ну, тогда - перебор, да. С другой стороны - думаю, производительность тут тоже - скорее «спортивный интерес», верно?

alex4321
()
Ответ на: комментарий от alex4321

Ну для себя да, вариант с нумпаем использовал бы

af5 ★★★★★
() автор топика

Пиши не по 1му байту в файл, а как уже сказали - набивай буфер размером хотя бы 64 тыщ байт (64Кб) например в строку, а потом уже эту строку сбрасывай в файл.

Добавление символа в массив, имхо, работает медленнее, чем добавление символа в строку. Ну и в файл строка быстрее должна писаться, чем массив.

Novator ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.