# For Monte Carlo simulation with same code same algorithm, how fast is Julia compared with Fortran?

**URL:** <https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021>\
**Category:** General Usage\
**Tags:** fortran, performance\
**Created:** [August 26, 2021, 7:44am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021 "2021-08-26T07:44:49Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [August 29, 2021, 7:19am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/42 "2021-08-29T07:19:07Z")

</div>

Isn’t this just `@unpack` from Parameters.jl?

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [August 29, 2021, 8:31am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/43 "2021-08-29T08:31:35Z")

</div>

The difference is as follows:

```julia
@unpackall_Foo foo

```

```julia
@unpack a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z = foo

```

It’s hard to be forced to use the latter style, so it would be great if someone clever could create a package to use the former style.

**Sample code**

Create a composite type with a lot of fields:

```julia
using ConcreteStructs

@concrete struct Foo a; b; c; d; e; f; g; h; i; j; k; l; m; n; o; p; q; r; s; t; u; v; w; x; y; z end

names = fieldnames(Foo)
kwargs = Expr(:parameters, (Expr(:kw, name, v) for (v, name) in enumerate(names))...)
@eval Foo($kwargs) = Foo($(names...))

foo = Foo(a = "meow", m = 'm', z = 99.99)

```

Output:

> Foo{String, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Char, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Float64}(“meow”, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ‘m’, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 99.99)

`@unpackall_Foo` case:

```julia
"""
`@unpackall_Foo(obj)` unpacks all fields of the object `obj` of type `Foo`.
"""
macro unpackall_Foo(obj)
    names = fieldnames(Foo)
    Expr(:(=),
        Expr(:tuple, names...),
        Expr(:tuple, (:($obj.$name) for name in names)...)
    ) |> esc
end

let
    @unpackall_Foo foo
    @show a b c d e f g h i j k l m n o p q r s t u v w x y z
end;

```

> **Output**
>
> ```julia
> a = "meow"
> b = 2
> c = 3
> d = 4
> e = 5
> f = 6
> g = 7
> h = 8
> i = 9
> j = 10
> k = 11
> l = 12
> m = 'm'
> n = 14
> o = 15
> p = 16
> q = 17
> r = 18
> s = 19
> t = 20
> u = 21
> v = 22
> w = 23
> x = 24
> y = 25
> z = 99.99
> 
> ```

`Parameters.@unpack` case:

```julia
using Parameters

let
    @unpack a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z = foo
    @show a b c d e f g h i j k l m n o p q r s t u v w x y z
end;

```

The output is the same as above.

Jupyter notebook: [https://github.com/genkuroki/public/blob/main/0018/How%20to%20define%20unpacking%20macros%20Part%202.ipynb](https://github.com/genkuroki/public/blob/main/0018/How%20to%20define%20unpacking%20macros%20Part%202.ipynb)

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [August 29, 2021, 11:59am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/44 "2021-08-29T11:59:05Z")

</div>

If you define your struct with `@with_kw`, Parameters.jl will also make a macro for you which does `@upack_all`. See [here](https://mauro3.github.io/Parameters.jl/stable/manual/#The-type-specific-(un)pack-all-macros-(somewhat-dangerous)).

Note: I would definitely consider this an anti-pattern. If your function _needs_ all of those variables in scope, it’s a sign you need to re-factor into smaller functions.

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [August 29, 2021, 6:57pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/45 "2021-08-29T18:57:07Z")

</div>

Oh! I hadn’t noticed [that part of the documentation](https://mauro3.github.io/Parameters.jl/v0.9/manual.html#The-type-specific-(un)pack-macros-(somewhat-dangerous)-1)! Thank you very much.

(What I’m having a little trouble with is [about the compatibility of `Parameters.@with_kw` and ConcreteStructs.jl](https://github.com/jonniedie/ConcreteStructs.jl/issues/4). ([[ANN] ConcreteStructs.jl](https://discourse.julialang.org/t/ann-concretestructs-jl-cut-the-boilerplate-when-concretely-parameterizing-structs/47274))

---

<div class="post-metadata">

**Author:** ![jonniedie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonniedie/32/12842_2.png) [@jonniedie](https://discourse.julialang.org/u/jonniedie)\
**Post date:** [August 30, 2021, 3:46pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/46 "2021-08-30T15:46:37Z")

</div>

I just put in a fix for ConcreteStructs to allow it to work with `Base.@kwdef`. `Parameters.@with_kw` doesn’t work, though.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 31, 2021, 6:34am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/47 "2021-08-31T06:34:49Z")

</div>

About 500 lines or so. It is prototype algorithm but it works very well and robust.  
But it will take me some time to appreciate the logic of Julia.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 31, 2021, 6:40am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/48 "2021-08-31T06:40:24Z")

</div>

Thank you very much for your suggestions.  
I used Julia 1.6.1. I used 3 methods as you suggested,

```
rn = rand(1)[1] 

rn = rand()

const RNG = MersenneTwister(100)
rn = rand(RNG)

```

In my code it does not make difference. It looks like the bottleneck is not the random number generator. Julia 1.6.1 seems smart enough in running random number generator.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 31, 2021, 7:11am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/49 "2021-08-31T07:11:49Z")

</div>

In my view, modern Fortran means the following:

1. f90 and above. Use modules to arrange the whole program in a neat and clear way.
2. implicit none, and use select kind to choose true real 8 or double precision.
3. flexible arrays. Whenever possible prevent using hard coded array size. Set array size as a variable, use allocatable arrays when needed.
4. Whenever possible, vectorize the code.
5. Use types to organize objects.
6. highly parallelized, especially MPI.

Thank you @Vasily_Pisarev @Sukera @genkuroki @DNF @lmiq @giordano @Henrique_Becker @ranocha @artkuo @ParadaCarleton etc (Sorry for the @ ten user limit…) Your help and comments are very crucial and very helpful!

The reason my Julia version is 3 times slower than Fortran, is probably because those const Ref stuff in my code caused a lot of unnecessary memory operations. Hopefully by removing them the code can reach the speed of Fortran.

I think Julia is promising. I also hope Julia can be more intelligent in optimizing the code when compiling. and do more `@`inline, `@`inbound, `@`turbo, `@`unpack, etc… tricks automatically. Personally I do not mind Julia spending some more seconds in compiling as long as it can do more optimization automatically.

In one word, I wish Julia could perhaps improve in a way that it can be more difficult for the user to write slow code.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [August 31, 2021, 7:40am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/50 "2021-08-31T07:40:58Z")

</div>

> [@CRquantum](#):
>
> In one word, I wish Julia could perhaps improve in a way that it can be more difficult for the user to write slow code.

Personally, I imagine something like a “performance” or “debug” mode which could, for example, throw warnings (or even errors?) when using non-constant globals or, as an option, errors on allocations in a certain block of code (useful for high performance engineering and embedded systems).

Note, though, that being able to write naive / slow / bad code is also an important feature, in particular for interactive usage.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [August 31, 2021, 12:26pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/51 "2021-08-31T12:26:27Z")

</div>

> [@CRquantum](#):
>
> In one word, I wish Julia could perhaps improve in a way that it can be more difficult for the user to write slow code.

Given that Julia’s design encourages highly abstract code, it’s hard to even define what code is slow without running it.  
Even the simplest case

```julia
function sum_itr(itr)
    s = 0
    for x in itr
        s += x
    end
    return s
end

```

is tricky: it is fast if `itr` has only integer values, and it has penalty due to type instability otherwise.

Such analysis is less of a problem when you have the end-user code where the types may be known at all call sites, but I can’t imagine a robust _a priori_ performance analysis of a library code in a general case (but of course the library devs can include in the test suite the specific argument types they assume important / representative).

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 31, 2021, 12:32pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/52 "2021-08-31T12:32:31Z")

</div>

> [@CRquantum](#):
>
> In one word, I wish Julia could perhaps improve in a way that it can be more difficult for the user to write slow code.

I really prefer my code to work first and performance can be continuously improved instead of re-writing it in a different language. It sounds like C/C++/Fortran are for you, where even the most verbose convoluted code is often not-too-slow

---

<div class="post-metadata">

**Author:** ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)\
**Post date:** [August 31, 2021, 12:54pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/53 "2021-08-31T12:54:49Z")

</div>

I hope we get a package that runs a function and just says, this is slow because of this etc. Basically an even more powerful [Dispatch Analysis · JETTest.jl](https://aviatesk.github.io/JETTest.jl/dev/toolset/dispatch/) . It already is amazing, but I hope it can get even better.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [September 1, 2021, 5:31am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/54 "2021-09-01T05:31:37Z")

</div>

I totally agree.  
Having ''performance" mode and “Debug” mode is like the “Release” Mode and “Debug” mode of the intel Fortran in Visual Studio.  
Wish Julia can throw more warning message when it finds some performance issues and tell user how to improve the code. In my point of view, being able to throw those ‘intelligent’ message can be really a “modern” feature for a modern language.  
Also wish Julia could have its own official IDE which is easy to use and debug, this can make Julia distinguished more from things like Python too.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [September 1, 2021, 5:39am UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/55 "2021-09-01T05:39:24Z")

</div>

Thank you very much for your efforts!

May I ask a stupid question, using the below structure as your said,

> [@Vasily\_Pisarev](#):
>
> `const GLOBAL_STATE_TO_GET_RID_OF = step_init(#=some arguments=#)`

Uhm, why it will be faster than defining many variables each with the const + Ref trick as the `Fortran’ like way I did?

---

<div class="post-metadata">

**Author:** ![alastair-marshall](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alastair-marshall/32/21418_2.png) [@alastair-marshall](https://discourse.julialang.org/u/alastair-marshall)\
**Post date:** [September 1, 2021, 12:08pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/56 "2021-09-01T12:08:05Z")

</div>

It seemed to me, from reading this thread, that using const + ref isn’t actually good for performance, maybe I got the wrong idea though

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 1, 2021, 12:09pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/57 "2021-09-01T12:09:36Z")

</div>

There are some nuances concerning that specific statement. But the take away is: Don’t use global variables!

---

<div class="post-metadata">

**Author:** ![alastair-marshall](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alastair-marshall/32/21418_2.png) [@alastair-marshall](https://discourse.julialang.org/u/alastair-marshall)\
**Post date:** [September 1, 2021, 12:13pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/58 "2021-09-01T12:13:54Z")

</div>

True, I just think if OPs code was written in a Julian way (rather than writing it as you’d write it in Fortran) the performance would be equivalent. I’ve never seen const + ref used in Julia (not that I’ve written anything huge in Julia I just simulate things) so I was a bit skeptical 😀

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 1, 2021, 12:16pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/59 "2021-09-01T12:16:09Z")

</div>

Yes, if the code was written more properly in Julia, the performance should be similar.

If you use const + ref to define scalars, is like defining every scalar as a one-element array, with a specific position in heap memory, carrying a pointer. Scalars do not need that, they are immutable and that allows many compiler optimizations.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [September 1, 2021, 3:47pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/60 "2021-09-01T15:47:49Z")

</div>

It’s not about performance, it’s about easy identification of a global variable used in a function, to facilitate further refactoring.

Continuing your analogy to video games difficulty level, the rules of the game include “No global variables. Period.” and you have to build your solution around that. Maybe find some module of yours with less than ten global variables and refactor that one first to get the hang of it. You’re really missing good bits of Julia with the Fortran approach IMO, like using `return` to return useful values, default argument values, keyword arguments, structs to organize computations etc.

---

<div class="post-metadata">

**Author:** ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)\
**Post date:** [September 1, 2021, 4:12pm UTC](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021/61 "2021-09-01T16:12:17Z")

</div>

I guess field `mu` and `sigma` of the struct `Mean_cov` are actually 2x2 array, right? We can make this faster by defining `Mean_cov` as:

```julia
struct Mean_cov
    mu::SMatrix{2, 2,Float64,4}
    sigma::SMatrix{2, 2,Float64,4}
    w::Float64
end

```

and make Mean\_cov immutable, so it can be stored inline in array (with the price that we can’t mutable them).

[Previous page](https://discourse.julialang.org/t/for-monte-carlo-simulation-with-same-code-same-algorithm-how-fast-is-julia-compared-with-fortran/67021.md?page=2)
