# \[ANN\] MonkeyLang.jl

**URL:** <https://discourse.julialang.org/t/ann-monkeylang-jl/74664>\
**Category:** Package Announcements\
**Tags:** repl, parser\
**Created:** [January 15, 2022, 12:29pm UTC](https://discourse.julialang.org/t/ann-monkeylang-jl/74664 "2022-01-15T12:29:53Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![jdad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdad/32/4739_2.png) [@jdad](https://discourse.julialang.org/u/jdad)\
**Post date:** [January 29, 2022, 4:36pm UTC](https://discourse.julialang.org/t/ann-monkeylang-jl/74664/21 "2022-01-29T16:36:52Z")

</div>

So now you get same kind of speed up than Go does get? Perfect!

All that was very interesting. Many thanks for the discussion. 🙂

---

<div class="post-metadata">

**Author:** ![lucifer1004](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucifer1004/32/22311_2.png) [@lucifer1004](https://discourse.julialang.org/u/lucifer1004)\
**Post date:** [January 29, 2022, 4:52pm UTC](https://discourse.julialang.org/t/ann-monkeylang-jl/74664/22 "2022-01-29T16:52:12Z")

</div>

Yes!

I have also learned a lot from you and @c42f. Thank you so much.

What I wonder now is why `Ref{Int}` is so slow here.

Found the answer in another post.

> [@Reference to Objects Very Slow](https://discourse.julialang.org/t/reference-to-objects-very-slow/963/2):
>
> `Ref` is an abstract type so you’ll get terrible performance when using it as the type of a slot.

After specifying the `Ref{Int}` fields as `Base.RefValue{Int}`, I got almost the same performance gains (but still slower than `mutable struct` + `Int`).

```julia
=== Using compiler ===
  10.557 s (583631370 allocations: 19.09 GiB)

```

---

<div class="post-metadata">

**Author:** ![jdad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdad/32/4739_2.png) [@jdad](https://discourse.julialang.org/u/jdad)\
**Post date:** [January 30, 2022, 10:29am UTC](https://discourse.julialang.org/t/ann-monkeylang-jl/74664/23 "2022-01-30T10:29:55Z")

</div>

For the record, here is my quick-and-dirty bash command (updated to get filename and line number in front) to analyze .mem files

```julia
(cd mems; for F in *.mem; do awk '{printf "%-20s %4.4d %s\n",FILENAME,NR,$0}' $F;done) | sort -nr -k3 >r.anamem.txt

```

Here are the results (2nd col. is line number in filename, 3rd col. is number of allocs)

```julia
vm.jl.408.mem 0091 11066672288 const_id = read_uint16(ins[ip+1:ip+2]) + 1
vm.jl.408.mem 0116 6688797472 pos = read_uint16(ins[ip+1:ip+2])
vm.jl.408.mem 0032 6415057712 vm.stack[vm.sp[]] = obj
vm.jl.408.mem 0103 6323812608 execute_binary_operation!(vm, op, left, right)
vm.jl.408.mem 0093 4742859504 push!(vm, vm.constants[const_id])
vm.jl.408.mem 0148 4026202560 push!(vm, vm.stack[frame.base_ptr+local_id])
vm.jl.408.mem 0209 1433313696 push!(vm, return_value)
vm.jl.408.mem 0324 477771248 frame = Frame(cl, vm.sp[] - arg_count)
lexer.jl.408.mem 0031 13440 ch, state = l.next
lexer.jl.408.mem 0135 5088 while isspace(read_char(l))
lexer.jl.408.mem 0103 3520 push!(chars, read_char(l))
vm.jl.408.mem 0030 3104 push!(vm.stack, obj
...

```

Sorry its Linux script, I am an old linuxer. I should have written that in Julia … next time surely

---

<div class="post-metadata">

**Author:** ![jdad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdad/32/4739_2.png) [@jdad](https://discourse.julialang.org/u/jdad)\
**Post date:** [January 30, 2022, 10:32am UTC](https://discourse.julialang.org/t/ann-monkeylang-jl/74664/24 "2022-01-30T10:32:17Z")

</div>

I also just saw this (found from reddit r/programming). It seems some optimisations are similar to the ones you got …

[https://medium.com/@mario.arias.c/comparing-implementations-of-the-monkey-language-vi-a-crystalline-update-2faac284c227](https://medium.com/@mario.arias.c/comparing-implementations-of-the-monkey-language-vi-a-crystalline-update-2faac284c227)

---

<div class="post-metadata">

**Author:** ![lucifer1004](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucifer1004/32/22311_2.png) [@lucifer1004](https://discourse.julialang.org/u/lucifer1004)\
**Post date:** [January 30, 2022, 10:58am UTC](https://discourse.julialang.org/t/ann-monkeylang-jl/74664/25 "2022-01-30T10:58:57Z")

</div>

Thanks for this link! I also found something interesting in [the Episode IV](https://medium.com/@mario.arias.c/comparing-implementations-of-the-monkey-language-iv-here-comes-a-new-challenger-crystal-2dd565071820). The author used Crystal macros to simplify some duplicate code, like below.

 ![Use macros to reduce duplicate code](https://global.discourse-cdn.com/julialang/original/3X/c/b/cbde96afa401fd627dc63461be943535decadb4b.png)

I think this is definitely what I can try next.

---

<div class="post-metadata">

**Author:** ![lucifer1004](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucifer1004/32/22311_2.png) [@lucifer1004](https://discourse.julialang.org/u/lucifer1004)\
**Post date:** [January 30, 2022, 11:04am UTC](https://discourse.julialang.org/t/ann-monkeylang-jl/74664/26 "2022-01-30T11:04:29Z")

</div>

BTW, I have just tried compiling the project to a standalone executable (you can have a try with `make build`), using [PackageCompiler.jl](https://github.com/JuliaLang/PackageCompiler.jl).

The compilation takes a long time, and the output size is very large. But I can run in my command line `monkey run hello_world.mo` or `monkey repl`, which is really nice.

One thing I found is the compiled executable ran much slower than directly using Julia (about 1.5x slower). Don’t know why.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [February 1, 2022, 12:09am UTC](https://discourse.julialang.org/t/ann-monkeylang-jl/74664/27 "2022-02-01T00:09:48Z")

</div>

> [@lucifer1004](#):
>
> After specifying the `Ref{Int}` fields as `Base.RefValue{Int}` , I got almost the same performance gains (but still slower than `mutable struct` + `Int` ).

Ah yes excellent find. I should probably have noticed this 🙂

This pattern in the standard library (and elsewhere) of using an abstract type like `Ref{Int}` as a constructor is nice for brevity in normal code (`Ref(1)` and `Ref{Int}()` both work). But it’s rather too easy to make the mistake of putting the same type names into a `struct`!

Lucikly JET (and also `@code_warntype`) will find this for you. For example

```julia
julia> using JET

julia> struct A
           x::Ref{Int}
       end

julia> a = A(Ref(1))
A(Base.RefValue{Int64}(1))

julia> f(a) = a.x[]
f (generic function with 1 method)

julia> @report_opt f(a)
═════ 1 possible error found ═════
┌ @ REPL[11]:1 Base.getindex(%1)
│ runtime dispatch detected: Base.getindex(%1::Ref{Int64})
└──────────────

```

[Previous page](https://discourse.julialang.org/t/ann-monkeylang-jl/74664.md?page=1)
