如何写"好"朱莉娅多种类型和数组打交道时,code [英] How to write "good" Julia code when dealing with multiple types and arrays

查看:179
本文介绍了如何写"好"朱莉娅多种类型和数组打交道时,code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的朱莉娅,并给予我的Matlab的起源,是有一些困难,决定如何写好朱莉娅code,它需要多个调度和朱莉娅的类型系统的优势。

I am new to Julia, and given my Matlab origins, am having some difficulty determining how to write "good" Julia code that takes advantage of multiple dispatch and Julia's type system.

考虑在那里我有,它提供了Float64的平方的函数的情况。我可能会这样写的:

Consider the case where I have a function that provides the square of a Float64. I might write this as:

function mysquare(x::Float64)
    return(x^2);
end

有时候,我想方所有Float64在一维数组,但不想写出来了 mysquare 每次一个循环,所以我使用了多个调度和添加以下内容:

Sometimes, I want to square all the Float64's in a 1-d array, but don't want to write out a loop over mysquare everytime, so I use multiple dispatch and add the following:

function mysquare(x::Array{Float64, 1})
    y = Array(Float64, length(x));
    for k = 1:length(x)
        y[k] = x[k]^2;
    end
    return(y);
end

但现在我有时Int64的工作,所以我写了两个函数,采取多分派的优势:

But now I am sometimes working with Int64, so I write out two more functions that take advantage of multiple dispatch:

function mysquare(x::Int64)
    return(x^2);
end
function mysquare(x::Array{Int64, 1})
    y = Array(Float64, length(x));
    for k = 1:length(x)
        y[k] = x[k]^2;
    end
    return(y);
end

这是正确的?还是有更多的朱莉娅的方式来处理这种情况?我应该使用类型参数也是这样吗?

Is this right? Or is there a more "Julia" way to deal with this situation? Should I use type parameters like this?

function mysquare{T<:Number}(x::T)
    return(x^2);
end
function mysquare{T<:Number}(x::Array{T, 1})
    y = Array(Float64, length(x));
    for k = 1:length(x)
        y[k] = x[k]^2;
    end
    return(y);
end

这感觉懂事,但我的code作为快速运行,那是我避免参数类型的情况?

This feels sensible, but will my code run as quickly as the case where I avoid parametric types?

在总之,有两部分,我的问题:

In summary, there are two parts to my question:

1)如果快速code是对我很重要,我应该使用上述参数类型,或者我应该写出来的多个版本不同的具体类型?或者我应该做别的东西完全?

1) If fast code is important to me, should I use parametric types as described above, or should I write out multiple versions for different concrete types? Or should I do something else entirely?

2)当我想,关于阵列以及标量操作的功能,它是很好的做法写函数的两个版本,一个是标量,和一个用于数组?或者我应该做别的东西完全?

2) When I want a function that operates on arrays as well as scalars, is it good practice to write two versions of the function, one for the scalar, and one for the array? Or should I be doing something else entirely?

最后,请大家指出,你可以在code想到的任何其他问题,如上面我的最终目标是在这里写出好朱莉娅code。

Finally, please point out any other issues you can think of in the code above as my ultimate goal here is to write good Julia code.

推荐答案

朱莉娅根据需要编译你的函数对每个组输入一个特定版本。从而回答部分1,不存在性能上的差异。该参数的方法是要走的路。

Julia compiles a specific version of your function for each set of inputs as required. Thus to answer part 1, there is no performance difference. The parametric way is the way to go.

至于第2部分,它可能在某些情况下,一个好主意,写一个单独的版本(有时出于性能原因,例如,以避免副本)。你的情况,但是你可以使用内置的宏 @ vectorize_1arg 来自动生成数组版本,例如

As for part 2, it might be a good idea in some cases to write a separate version (sometimes for performance reasons, e.g. to avoid a copy). In your case however you can use the in-built macro @vectorize_1arg to automatically generate the array version, e.g.

function mysquare{T<:Number}(x::T)
    return(x^2)
end
@vectorize_1arg Number mysquare
println(mysquare([1,2,3]))

对于一般的风格,不要用分号,而 mysquare(X ::数)= X ^ 2 是短了很多。

至于你的矢量mysquare,考虑的情况下,其中 T BigFloat 。你的输出数组,但是,是 Float64 。处理这一种方法是将其更改为

As for your vectorized mysquare, consider the case where T is a BigFloat. Your output array, however, is Float64. One way to handle this would be to change it to

function mysquare{T<:Number}(x::Array{T,1})
    n = length(x)
    y = Array(T, n)
    for k = 1:n
        @inbounds y[k] = x[k]^2
    end
    return y
 end

在那里我已经添加了 @inbounds 宏来提高速度,因为我们不需要检查约束违规每次 - 我们知道长度。此功能还可以有问题的事件T ^ 2的类型不是T.一个甚至更多的防守版本可以说是够

where I've added the @inbounds macro to boost speed because we don't need to check the bound violation everytime - we know the lengths. This function could still have issues in the event that the type of T^2 isn't T. An even more defensive version would perhaps be

function mysquare{T<:Number}(x::Array{T,1})
    n = length(x)
    y = Array(typeof(one(T)^2), n)
    for k = 1:n
        @inbounds y[k] = x[k]^2
    end
    return y
 end

其中,一(T)会给 1 如果 T 是一个int,而 1.0 如果 T 是一个Float64,等等。如果你想使超强劲库code这些因素只有物质。如果你真的只将处理Float64s或东西,可以晋升到Float64s,那么它是不是一个问题。这似乎是艰苦的工作,但功率是惊人的。您可以随时只是解决的Python一样的性能和不顾一切类型的信息。

where one(T) would give 1 if T is an Int, and 1.0 if T is a Float64, and so on. These considerations only matter if you want to make hyper-robust library code. If you really only will be dealing with Float64s or things that can be promoted to Float64s, then it isn't an issue. It seems like hard work, but the power is amazing. You can always just settle for Python-like performance and disregard all type information.

这篇关于如何写&QUOT;好&QUOT;朱莉娅多种类型和数组打交道时,code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆