如何声明插值函数的类型?

为了提高运行速度,我希望在写函数的时候,声明每个变量的类型。其中一个变量为插值函数。

using Interpolation

typeof(LinearInterpolation([1.,2,3],[1.,2,3]))

我通过如上方式,查看LinearInterpolation返回的类型。结果非常复杂,我看不懂:

Interpolations.Extrapolation{Float64, 1, Interpolations.GriddedInterpolation{Float64, 1, Float64, Gridded{Linear{Throw{OnGrid}}}, Tuple{Vector{Float64}}}, Gridded{Linear{Throw{OnGrid}}}, Throw{Nothing}}

那么,我到底如何声明这是插值函数呢?

为了提高运行速度,我希望在写函数的时候,声明每个变量的类型。

你这里可能有些误解。在类型可推断的情况下,声明变量类型并不会让速度变快。

查看LinearInterpolation 返回的类型。结果非常复杂,我看不懂:

你可以直接声明类型为 Extrapolation 或者 AbstractInterpolation 或者 AbstractArray. 但除非你是想要做多重派发,否则着实没必要.

那么在VS Code中调试的时候(改一下,运行一下,应该都是第一次运行吧),不声明变量会不会额外别浪费编译时间?比如我写的函数有10个参数,即使每个变量只有2种类型,估计也有1024种搭配了。是不是它会编译成1024种搭配?然后1kB变1MB?

另外请问AbstractArray是如何查询的?这看起来……已经和Interpolation八竿子打不着了吧

不是这样的,我们存在两个概念:

  • 方法 (method): 比如说 f(x) = x+x 这是一个方法
  • 方法实例: 比如说第一次执行 f(2) 时需要编译的内容是 f(x::Int) 这个实例
julia> using MethodAnalysis

julia> f(x) = x+x
f (generic function with 1 method)

julia> methodinstances(f) # 定义一个方法并不会触发任何编译
Core.MethodInstance[]

julia> f(1) # 第一次执行会编译 f(::Int) 方法
2

julia> methodinstances(f)
1-element Vector{Core.MethodInstance}:
 MethodInstance for f(::Int64)

julia> f(1.0) # 第一次执行会编译 f(::Float64) 方法
2.0

julia> methodinstances(f)
2-element Vector{Core.MethodInstance}:
 MethodInstance for f(::Int64)
 MethodInstance for f(::Float64)

需要编译多久以及编译出来的内容有多大,取决于要编译多少个方法实例,并不取决于你的方法定义中类型是否具体。

我在 Day2 - 陈久宁 - Julia代码中的典型设计模式_哔哩哔哩_bilibili 也介绍了这个概念,如果有兴趣的话可以看一看。

1 个赞

另外请问AbstractArray 是如何查询的?这看起来……已经和Interpolation 八竿子打不着了吧

一个是直接阅读源代码,还有一个是可以通过 supertype 来查询,比如说

julia> supertype(Interpolations.Extrapolation)
AbstractExtrapolation

然后一层一层往上查,发现其实是 AbstractArray 类型。

1 个赞

好好好,现在去看。谢谢大佬 :heart: