Generate function code

Hellow!

I have

type_list = [
    # type     code
    #
    Int64      0x11;
    Int32      0xa2;
    Int16      0x33;
    Int8       0x24;

    #
    UInt64     0x15;
    UInt32     0xb6;
    UInt16     0x7a;
    UInt8      0x8f;

    #
    Float64    0x92;
    Float32    0x0a;
    Float16    0x0b;
]

I need:

function get_type_by_code(code::UInt8)
    code == 0x11 && return Int64
    code == 0xa2 && return Int32
    code == 0x33 && return Int16
    code == 0x24 && return Int8
    code == 0x15 && return UInt64
    code == 0xb6 && return UInt32
    code == 0x7a && return UInt16
    code == 0x8f && return UInt8
    code == 0x92 && return Float64
    code == 0x0a && return Float32
    code == 0x0b && return Float16
end

I do:

code_string = "function get_type_by_code(code::UInt8)\n"
for i = 1 : length(type_list[:,1])
    code_string *= "    code == $(type_list[i,2]) && return $(type_list[i,1])\n"
end
code_string *= "end"
Base.include_string(Main, code_string)

how to make it better?

Firstly, you should use a Dict rather than a Matrix. Once you do, is this good enough?

get_type_by_code(code) = type_list[code]
const type_list = Dict(
     0x11 => Int64,
     0xa2 => Int32,
     0x33 => Int16,
     0x24 => Int8,

     0x15 => UInt64,
     0xb6 => UInt32,
     0x7a => UInt16,
     0x8f => UInt8,

     0x92 => Float64,
     0x0a => Float32,
     0x0b => Float16,
)

and then just type_list[0x11] to get Int64

1 Like

No, i need exactly this function by example:

function get_type_by_code(code::UInt8)
    code == 0x11 && return Int64
    code == 0xa2 && return Int32
    code == 0x33 && return Int16
    code == 0x24 && return Int8
    code == 0x15 && return UInt64
    code == 0xb6 && return UInt32
    code == 0x7a && return UInt16
    code == 0x8f && return UInt8
    code == 0x92 && return Float64
    code == 0x0a && return Float32
    code == 0x0b && return Float16
end
const type_list2 = Dict(
     0x11 => Int64,
     0xa2 => Int32,
     0x33 => Int16,
     0x24 => Int8,

     0x15 => UInt64,
     0xb6 => UInt32,
     0x7a => UInt16,
     0x8f => UInt8,

     0x92 => Float64,
     0x0a => Float32,
     0x0b => Float16,
)

using BenchmarkTools
@btime type_list2[0x92]  # 1.900 ns (0 allocations: 0 bytes)
@btime get_type_by_code(0x92)  # 0.001 ns (0 allocations: 0 bytes)

this is done for convenience and speed, the function is not one,
I edit only main list, then code generation

Я делаю:

code_string = "function get_type_by_code(code::UInt8)\n"
for i = 1 : length(type_list[:,1])
    code_string *= "    code == $(type_list[i,2]) && return $(type_list[i,1])\n"
end
code_string *= "end"
Base.include_string(Main, code_string)

как сделать лучше?

There’s no such thing as pico-second function evaluations (this is a common confusion, and the result of constant propagation in the compiler). Using the Ref trick from the BenchmarkTools docs, and placing the Dict into a function for similar effect, we see they’re much more similar than that:

julia> get_type_by_code_dict(x) = type_list2[x];

julia> @btime get_type_by_code_dict($(Ref(0x92))[])
  6.828 ns (0 allocations: 0 bytes)
Float64

julia> @btime get_type_by_code($(Ref(0x92))[])
  3.266 ns (0 allocations: 0 bytes)
Float64

You can use a Base.ImmutableDict to regain that speed in this case:

julia> const type_list_imm = Base.ImmutableDict(
            0x11 => Int64,
            0xa2 => Int32,
            0x33 => Int16,
            0x24 => Int8,

            0x15 => UInt64,
            0xb6 => UInt32,
            0x7a => UInt16,
            0x8f => UInt8,

            0x92 => Float64,
            0x0a => Float32,
            0x0b => Float16,
       );

julia> get_type_by_code_imdict(x) = type_list_imm[x];

julia> @btime get_type_by_code_imdict($(Ref(0x92))[])
  3.292 ns (0 allocations: 0 bytes)
Float64

julia> @btime get_type_by_code($(Ref(0x92))[])
  3.268 ns (0 allocations: 0 bytes)
Float64

That said, if you really want to create such a function from your Dict, you should not use strings but rather Exprs (expressions). The Metaprogramming section of the julia manual is a great place to start learning how to do this.

4 Likes

How about value types? One essentially can do pattern matching with them just by using multiple dispatch feature.