Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Как усорить код?

Азамат Каламов Знаток (290), открыт 3 недели назад
Если что запускаю в termux
мой код:

from func import *
from progress.bar import IncrementalBar
from time import time

scr = Screen()
scr.fill(Color(0, 0, 0))

bar = IncrementalBar('Rendering', max=scr.size.x*scr.size.y)

start_time = time()

for y in range(scr.size.y):
for x in range(scr.size.x):
main(scr, vec2(x=x, y=y))
bar.next()

bar.finish()
scr.save()

end_time = time()
execution_time = end_time - start_time
print(f"Завершено! Время выполнения: {int(execution_time)} секунд")



функция main:

def main(scr:Screen, pixel:vec2):
x = pixel.x / scr.size.x * 2 - 1
y = pixel.y / scr.size.y * 2 - 1
x *= scr.aspect

scr.setPixel(pixel.x, pixel.y, Color(0,0,0))

if x*x+y*y <= 0.5:
scr.setPixel(pixel.x, pixel.y, Color(255,255,255))
2 ответа
бабуин гибонович Оракул (50560) 3 недели назад
 from func import * 
from progress.bar import IncrementalBar
from time import time
from concurrent.futures import ThreadPoolExecutor

scr = Screen()
scr.fill(Color(0, 0, 0))

bar = IncrementalBar('Rendering', max=scr.size.x * scr.size.y)

def process_pixel(pixel):
x = pixel.x / scr.size.x * 2 - 1
y = pixel.y / scr.size.y * 2 - 1
x *= scr.aspect

if x * x + y * y <= 0.5:
scr.setPixel(pixel.x, pixel.y, Color(255, 255, 255))
else:
scr.setPixel(pixel.x, pixel.y, Color(0, 0, 0))

bar.next()

start_time = time()

pixels = [vec2(x=x, y=y) for y in range(scr.size.y) for x in range(scr.size.x)]

with ThreadPoolExecutor() as executor:
executor.map(process_pixel, pixels)

bar.finish()
scr.save()

end_time = time()
execution_time = end_time - start_time
print(f"Завершено! Время выполнения: {int(execution_time)} секунд")
 import numpy as np 
from func import *
from progress.bar import IncrementalBar
from time import time

scr = Screen()
scr.fill(Color(0, 0, 0))

bar = IncrementalBar('Rendering', max=scr.size.x * scr.size.y)

start_time = time()

x = np.linspace(-1, 1, scr.size.x) * scr.aspect
y = np.linspace(-1, 1, scr.size.y)

X, Y = np.meshgrid(x, y)
mask = X**2 + Y**2 <= 0.5

for j in range(scr.size.y):
for i in range(scr.size.x):
if mask[j, i]:
scr.setPixel(i, j, Color(255, 255, 255))
else:
scr.setPixel(i, j, Color(0, 0, 0))
bar.next()

bar.finish()
scr.save()

end_time = time()
execution_time = end_time - start_time
print(f"Завершено! Время выполнения: {int(execution_time)} секунд")
Азамат КаламовЗнаток (290) 3 недели назад
мой код срабатывает примерно за 130 сек, ваш первый: не дождался(ждал мин 5), ваш второй: 190. Точнее не ваш а нейросети
бабуин гибонович Оракул (50560) Азамат Каламов, Спасибо за ваш отзыв. Давайте попробуем дополнительные оптимизации. Профилирование Первый шаг — профилировать ваш код, чтобы найти узкие места. Можно использовать модуль cProfile.
бабуин гибоновичОракул (50560) 3 недели назад
 import cProfile 

def main_profiling():
scr = Screen()
scr.fill(Color(0, 0, 0))

bar = IncrementalBar('Rendering', max=scr.size.x * scr.size.y)

start_time = time()

for y in range(scr.size.y):
for x in range(scr.size.x):
main(scr, vec2(x=x, y=y))
bar.next()

bar.finish()
scr.save()

end_time = time()
execution_time = end_time - start_time
print(f"Завершено! Время выполнения: {int(execution_time)} секунд")

cProfile.run('main_profiling()')
бабуин гибоновичОракул (50560) 3 недели назад
Оптимизация алгоритма
Теперь давайте попробуем оптимизировать сам алгоритм.

Предварительная проверка условия: Перенесем проверку условия перед установкой пикселя.
Уменьшение числа вызовов методов: Сохраним ссылки на часто вызываемые методы, чтобы уменьшить накладные расходы.
бабуин гибоновичОракул (50560) 3 недели назад
 from func import * 
from progress.bar import IncrementalBar
from time import time

scr = Screen()
scr.fill(Color(0, 0, 0))

bar = IncrementalBar('Rendering', max=scr.size.x * scr.size.y)

start_time = time()


бабуин гибоновичОракул (50560) 3 недели назад
 set_pixel = scr.setPixel  
aspect = scr.aspect
width, height = scr.size.x, scr.size.y

for y in range(height):
for x in range(width):
# Предварительные расчеты
norm_x = x / width * 2 - 1
norm_y = y / height * 2 - 1
norm_x *= aspect

# Проверка условия и установка пикселя
if norm_x * norm_y <= 0.5:
set_pixel(x, y, Color(255, 255, 255))
else:
set_pixel(x, y, Color(0, 0, 0))

bar.next()

bar.finish()
scr.save()

end_time = time()
execution_time = end_time - start_time
print(f"Завершено! Время выполнения: {int(execution_time)} секунд")
бабуин гибоновичОракул (50560) 3 недели назад
Оптимизация с использованием Numba
Модуль numba может значительно ускорить численные операции.

Установите numba: pip install numba
Используйте numba для компиляции функции main.
бабуин гибоновичОракул (50560) 3 недели назад
 from numba import jit 
from func import *
from progress.bar import IncrementalBar
from time import time

scr = Screen()
scr.fill(Color(0, 0, 0))

bar = IncrementalBar('Rendering', max=scr.size.x * scr.size.y)

@jit(nopython=True)
def compute_color(x, y, width, height, aspect):
norm_x = x / width * 2 - 1
norm_y = y / height * 2 - 1
norm_x *= aspect

if norm_x * norm_y <= 0.5:
return (255, 255, 255)
else:
return (0, 0, 0)

start_time = time()

width, height = scr.size.x, scr.size.y
aspect = scr.aspect

for y in range(height):
for x in range(width):
color = compute_color(x, y, width, height, aspect)
scr.setPixel(x, y, Color(*color))

бабуин гибоновичОракул (50560) 3 недели назад
         bar.next()  

bar.finish()
scr.save()

end_time = time()
execution_time = end_time - start_time
print(f"Завершено! Время выполнения: {int(execution_time)} секунд")
бабуин гибоновичОракул (50560) 3 недели назад
Попробуйте этот обновленный подход и посмотрите, ускоряет ли он выполнение вашего кода.
бабуин гибонович, жаль, что администрация перманентом не банит ответы от нейросети...
Sergio 2.1 Оракул (67615) 3 недели назад
 from func import * 
from time import time
import numpy as np

def optimized_main(scr: Screen):
x = np.linspace(-scr.aspect, scr.aspect, scr.size.x)
y = np.linspace(-1, 1, scr.size.y)
X, Y = np.meshgrid(x, y)
mask = X*X + Y*Y <= 0.5
black = Color(0, 0, 0)
white = Color(255, 255, 255)
for y in range(scr.size.y):
for x in range(scr.size.x):
color = white if mask[y, x] else black
scr.setPixel(x, y, color)

def main():
scr = Screen()
scr.fill(Color(0, 0, 0))
start_time = time()
optimized_main(scr)
scr.save()
end_time = time()
execution_time = end_time - start_time
print(f"Завершено! Время выполнения: {int(execution_time)} секунд")

if __name__ == "__main__":
main()
 from func import * 
from time import time
from concurrent.futures import ThreadPoolExecutor
import multiprocessing

def process_chunk(args):
scr, start_y, end_y = args
for y in range(start_y, end_y):
for x in range(scr.size.x):
x_norm = x / scr.size.x * 2 - 1
y_norm = y / scr.size.y * 2 - 1
x_norm *= scr.aspect
if x_norm*x_norm + y_norm*y_norm <= 0.5:
scr.setPixel(x, y, Color(255, 255, 255))
else:
scr.setPixel(x, y, Color(0, 0, 0))

def parallel_main(scr: Screen):
num_cores = multiprocessing.cpu_count()
chunk_size = scr.size.y // num_cores
chunks = []
for i in range(num_cores):
start_y = i * chunk_size
end_y = start_y + chunk_size if i < num_cores-1 else scr.size.y
chunks.append((scr, start_y, end_y))
with ThreadPoolExecutor(max_workers=num_cores) as executor:
executor.map(process_chunk, chunks)

def main():
scr = Screen()
scr.fill(Color(0, 0, 0))
start_time = time()
parallel_main(scr)
scr.save()
end_time = time()
execution_time = end_time - start_time
print(f"Завершено! Время выполнения: {int(execution_time)} секунд")

if __name__ == "__main__":
main()
Похожие вопросы