lenguaje language docs codes benchmarking octave julia-lang

benchmarking - language - julia vs r



¿Es el idioma Julia realmente tan rápido como dice? (2)

Después de esta publicación , decidí comparar a Julia con GNU Octave y los resultados fueron inconsistentes con las aceleraciones ilustradas en julialang.org .

CXXFLAGS=''-std=c++11 -O3'' tanto Julia como GNU Octave con CXXFLAGS=''-std=c++11 -O3'' , los resultados que obtuve:

GNU Octave

a=0.9999; tic;y=a.^(1:10000);toc Elapsed time is 0.000159025 seconds. tic;y=a.^(1:10000);toc Elapsed time is 0.000162125 seconds. tic;y=a.^(1:10000);toc Elapsed time is 0.000159979 seconds.

-

tic;y=cumprod(ones(1,10000)*a);toc Elapsed time is 0.000280142 seconds. tic;y=cumprod(ones(1,10000)*a);toc Elapsed time is 0.000280142 seconds. tic;y=cumprod(ones(1,10000)*a);toc Elapsed time is 0.000277996 seconds.

Julia

tic();y=a.^(1:10000);toc() elapsed time: 0.003486508 seconds tic();y=a.^(1:10000);toc() elapsed time: 0.003909662 seconds tic();y=a.^(1:10000);toc() elapsed time: 0.003465313 seconds

-

tic();y=cumprod(ones(1,10000)*a);toc() elapsed time: 0.001692931 seconds tic();y=cumprod(ones(1,10000)*a);toc() elapsed time: 0.001690245 seconds tic();y=cumprod(ones(1,10000)*a);toc() elapsed time: 0.001689241 seconds

¿Podría alguien explicar por qué Julia es más lenta que GNU Octave con estas operaciones básicas? Después de calentado, debería llamar a LAPACK / BLAS sin gastos generales, ¿verdad?

EDITAR:

Como se explica en los comentarios y respuestas, el código anterior no es un buen punto de referencia ni ilustra los beneficios de usar el idioma en una aplicación real. Solía ​​pensar en Julia como un "Octave / MATLAB" más rápido, pero es mucho más que eso. Es un gran paso hacia la computación científica productiva y de alto rendimiento. Al usar Julia, pude: 1) superar el rendimiento del software en mi campo de investigación escrito en Fortran y C ++, y 2) proporcionar a los usuarios una API mucho más agradable.


Estás usando variables globales, que es una interpretación conseguida en Julia.

El problema es que los globales pueden cambiar de tipo cada vez que su código llame a la función antera. Como resultado, el compilador tiene que generar un código extremadamente lento que no puede hacer suposiciones sobre los tipos de variables globales que se utilizan.

Las modificaciones simples de su código en línea con https://docs.julialang.org/en/stable/manual/performance-tips/ deberían arrojar resultados más satisfactorios.


Las operaciones vectorizadas como .^ Son exactamente el tipo de cosas en las que Octave es bueno porque en realidad están implementadas en su totalidad en código C especializado. En algún lugar del código que se compila cuando se construye Octave, hay una función C que calcula .^ Para un doble y un conjunto de dobles: eso es lo que realmente está cronometrando aquí, y es rápido porque está escrito en C. Julia .^ operador, por otro lado, está escrito en Julia:

julia> a = 0.9999; julia> @which a.^(1:10000) .^(x::Number,r::Ranges{T}) at range.jl:327

Esa definición consiste en esto:

.^(x::Number, r::Ranges) = [ x^y for y=r ]

Utiliza una comprensión de matriz unidimensional para elevar x a cada valor y en el rango r , devolviendo el resultado como un vector.

Edward Garson tiene toda la razón de que uno no debería usar los globales para un rendimiento óptimo en Julia. La razón es que el compilador no puede razonar muy bien sobre los tipos de globales porque pueden cambiar en cualquier punto donde la ejecución abandona el alcance actual. Salir del alcance actual no suena como sucede a menudo, pero en Julia, incluso cosas básicas como indexar en una matriz o agregar dos enteros son en realidad llamadas a métodos y, por lo tanto, dejan el alcance actual. En el código de esta pregunta, sin embargo, todo el tiempo se gasta dentro de la función .^ , Por lo que el hecho de que a sea ​​global no importa:

julia> @elapsed a.^(1:10000) 0.000809698 julia> let a = 0.9999; @elapsed a.^(1:10000) end 0.000804208

En definitiva, si todo lo que estás haciendo es llamar a operaciones vectorizadas en matrices de coma flotante, Octave está bien. Sin embargo, a menudo no es en realidad el lugar donde se usa la mayor parte del tiempo, incluso en lenguajes dinámicos de alto nivel. Si alguna vez desea iterar sobre una matriz con un bucle for, operando en cada elemento con aritmética escalar, encontrará que Octave es bastante lento en ese tipo de cosas, a menudo miles de veces más lento que el código C o Julia. la misma cosa. Escribir sobre los bucles en Julia, por otro lado, es algo perfectamente razonable que hacer, de hecho, todo nuestro código de clasificación está escrito en Julia y es comparable a C en el rendimiento. También hay muchas otras razones para usar Julia que no tienen que ver con el rendimiento. Como clon de Matlab, Octave hereda muchos de los problemas de diseño de Matlab y no le va muy bien como lenguaje de programación de propósito general. Por ejemplo, no querría escribir un servicio web en Octave o Matlab, pero es muy fácil hacerlo en Julia.