performance - Julia - 具有属性的可变结构,它是一个函数和@code_warntype

标签 performance struct julia

在 Julia 中,我想要一个可变结构,其属性类型为函数,该函数将有参数:

mutable struct Class_example
    function_with_arguments::Function
    some_attribute::Int
    function Class_example() new() end
    function Class_example(function_wa::Function, some_a::Int)
        this = new()
        this.function_with_arguments = function_wa
        this.some_attribute = some_a
        this
    end
end

我也想对这个可变结构做一个 Action :
function do_action_on_class(Class::Class_example)
    return Class.function_with_arguments(Class.some_attribute ,2.0, true)
end

然后我定义了一个旨在成为我的类属性的函数:
function do_something_function(arg1::Int, arg2::Float64, arg3::Bool)
    if arg2 < 5.0
        for i in 1:arg1
            # Do Something Interesting
            @show arg3
        end
    end
    return 1
end

最后,function_whith_arguments将在我的整个项目中启动大量时间,这只是一个最小的示例,所以我希望所有这些代码都非常快。这就是我根据 Julia 的文档 Performance Tips 使用 @code_warntype 的原因。

但是,@code_warntype 告诉我这个
body::Any
15 1 ─ %1 = (Base.getfield)(Class, :function_with_arguments)::Function
getproperty
%2 = (Base.getfield)(Class, :some_attribute)::Int64
%3 = (%1)(%2, 2.0, true)::Any                                     │ 
return %3              

在这里,::Function和两个 ::Any红色,表示 Julia 可以通过更好的实现来提高代码的性能。那么这个正确的实现是什么?我应该如何在我的可变结构中将我的属性 function_whith_arguments 声明为 Function 类型?

整个代码可编译:
mutable struct Class_example
    function_with_arguments::Function
    some_attribute::Int
    function Class_example() new() end
    function Class_example(function_wa::Function, some_a::Int)
        this = new()
        this.function_with_arguments = function_wa
        this.some_attribute = some_a
        this
    end
end


function do_action_on_class(Class::Class_example)
    return Class.function_with_arguments(Class.some_attribute ,2.0, true)
end

function do_something_function(arg1::Int, arg2::Float64, arg3::Bool)
    if arg2 < 5.0
        for i in 1:arg1
            # Do Something Interesting
            @show arg3
        end
    end
    return 1
end

function main()
    class::Class_example = Class_example(do_something_function, 4)
    @code_warntype do_action_on_class(class)
end

main()

最佳答案

这将是有效的(很好推断)。请注意,我只修改(并重命名)了类型。

mutable struct MyClass{F<:Function}
    function_with_arguments::F
    some_attribute::Int
end


function do_action_on_class(Class::MyClass)
    return Class.function_with_arguments(Class.some_attribute ,2.0, true)
end

function do_something_function(arg1::Int, arg2::Float64, arg3::Bool)
    if arg2 < 5.0
        for i in 1:arg1
            # Do Something Interesting
            @show arg3
        end
    end
    return 1
end

function main()
    class::MyClass = MyClass(do_something_function, 4)
    @code_warntype do_action_on_class(class)
end

main()

我做了什么?
  • 如果你关心性能,你应该never have fields of an abstract type , 和 isabstracttype(Function) == true .你应该做的是参数化该字段类型(上面的 F,它可以是任何函数。注意 isconcretetype(typeof(sin)) == true)。这样,对于 MyCall 的任何特定实例每个字段的精确具体类型在编译时是已知的。
  • 与性能无关,但是:不需要简单地将所有参数分配给所有字段的构造函数。这样的constructor默认情况下是隐式定义的。

  • 您可以阅读有关参数类型的更多信息 here .

    顺便说一句,您所做的看起来很像尝试在 Julia 中编写 OO 风格。我建议不要这样做,而是使用 Julia 使用多次调度的 Julia 方式。

    关于performance - Julia - 具有属性的可变结构,它是一个函数和@code_warntype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52992375/

    相关文章:

    sql - 在连续 block 中查询具有相同值的最后一条记录

    arrays - Hive Array<Struct<>>插入显示null

    iphone - 在类之间共享结构信息 - Objective C - OpenGL ES

    c++ - 没有可用于结构 vector 的成员

    argument-passing - 将附加参数传递给内置函数

    types - 如何判断一个类型来自哪个模块?

    module - 尝试在 Julia 中加载包

    python - 为什么调用 time.sleep 或 subprocess.Popen 后 Python 操作会慢 30 倍?

    mongodb - MongoDB 是为大量更新而构建的吗?

    java - 加速展开/折叠 JTree 的所有节点