Pull to refresh

Comments 13

Старый добрый Фортран. Один из моих первых языков программирования. Помню, как писал на нем первые лабы.

Лучше дружить питон с Julia

Код из вашего примера(без fortran)
Код из вашего примера(без fortran)

за статью спасибо, если когда-нибудь пригодится, попробую что-то написать на fortran

Или ноутбук какой то очень старый, или его совсем замусорили, но на телефоне фрактал генерировался меньше 5 секунд.

REAL(8) непереносимо и не рекомендуется к употреблению. Если почему-то нет уверенности в дефолтном DOUBLE PRECISION, то лучше использовать REAL64 из ISO_FORTRAN_ENV.

import time
import numpy as np
import matplotlib.pyplot as plt
from numba import jit, prange


@jit(nopython=True, parallel=True, fastmath=True)
def mandelbrot_numba(height, width, max_iter):
    output = np.zeros((height, width), dtype=np.int32)

    for i in prange(height):
        y0 = -1.5 + (i * 3.0) / height
        for j in range(width):
            x0 = -2.0 + (j * 3.0) / width
            x, y = 0.0, 0.0
            iteration = 0

            while (x * x + y * y <= 4.0) and (iteration < max_iter):
                xtemp = x * x - y * y + x0
                y = 2.0 * x * y + y0
                x = xtemp
                iteration += 1

            output[i, j] = iteration

    return output


if __name__ == "__main__":
    height, width = 2000, 2000
    max_iter = 100

    print("Начинаем расчёт фрактала с Numba...")
    start = time.time()
    image = mandelbrot_numba(height, width, max_iter)
    end = time.time()

    print(f"Расчёт занял: {end - start:.2f} секунд")

    plt.figure(figsize=(10, 6))
    plt.imshow(image, cmap='hot', origin='upper')
    plt.title("Множество Мандельброта (Python, наивная реализация)")
    plt.axis('off')
    plt.tight_layout()
    plt.show()

Код без оптимизации отработал за 20.60 секунд, но с оптимизацией (jit) за 1.25 секунд

Можно без нумбы, питон сам все может векторизвать, а если заменить numpy, на cupy то и на видяхе будет считать

Это не "питон умеет", он этого не умеет сам по себе и не планирует. Это некоторые библиотеки хорошо написаны на тех же C++/Fortran/CUDA.

а допустим с Cython сравнивали по скорости?

Кроме того у кода на Фортране не учтен порядок перебора индексов в массиве. Они меняются снаружи внутрь. Т.е. самый быстро меняющийся будет левый индекс, а не как в С - правый.

Такая реализация ведёт к промахам по памяти.

Лучше переписать на более корректную.

Так и не понял, почему именно Fortran, а не C++. Выстрелить в ногу можно где угодно, было бы желание.

Как человек, в своё время несколько лет писавший по работе на Фортране, искренне не понимаю, почему из всех компилируемых языков выбран именно он. Тем более преимущества Фортрана (операции над массивами) не используются.

Сделал такой же тест с помощью Фикуса (репозиторий).

import Sys
import Image.Encoder as enc

fun mandelbrot_ficus(height: int, width: int, max_iter: uint8): uint8[,] {

    val output = array((height, width), 0u8)

    @parallel
    for i <- 0:height {
        // Преобразуем координаты пикселя в координаты на плоскости
        val y0 = -1.5f + ((i :> float) * 3.0f) / (height :> float)

        @parallel
        for j <- 0:width {
            val x0 = -2.0f + ((j :> float) * 3.0f) / (width :> float)
            var x = 0.0f
            var y = 0.0f
            var iteration = 0u8

            // Тот самый "тяжелый" цикл
            while (x * x + y * y <= 4.0f) && (iteration < max_iter) {
                iteration = ((iteration + 1u8) :> uint8)
                val xtemp = x * x - y * y + x0
                y = 2.0f * x * y + y0
                x = xtemp
            }

            output[i, j] = iteration
        }
    }

    return output
}

var img = array((1,1), 0u8)

val (gmean, _) = Sys.timeit(fun () { 
    img = mandelbrot_ficus(2000, 2000, 100u8) 
})

println(f"Время расчёта: {gmean * 1000.:.2f}мс")

enc.imwrite("mandelbrot.png", img)

На моем ноутбуке этот тест работает за 40мс примерно.

Если убрать директивы @parallel с 8 и 13 строк, тогда тест работает 195мс.

Тест на Питоне 12.28 сек.

Sign up to leave a comment.

Articles