我想创建一个struct
mutable struct myStruct
id::string
end我确实希望id是一个字符串,但我希望它只接受3个值中的一个(例如"a"、"b"或"c")。我的想法是理论上可以加速行动。
发布于 2020-03-20 21:55:57
我不知道如何让id成为一个String,同时限制它只有3个可能的值中的一个,这样编译器就可以利用它。
但是,如果离开String域是一种选择,则有几种可能性。让我们试着在这里测试其中的一些。为了示例起见,让我们假设这个id字段用于测试两个MyStruct实例之间的相等性。
这类类型的一个可能的(极简式)泛型实现如下所示,其中参数T确定用于id的类型。
mutable struct MyType{T}
id :: T
end
# Two MyType instances are equal if their ids are equal
import Base.==
==(a::MyType{T}, b::MyType{T}) where {T} = (a.id == b.id)现在,让我们在各种情况下对相等操作符进行基准测试。首先,使用字符串作为标识符的基本大小写:
julia> using BenchmarkTools
julia> a = MyType("apple")
MyType{String}("apple")
julia> b = MyType("banana")
MyType{String}("banana")
julia> @btime $a == $b
4.326 ns (0 allocations: 0 bytes)
false我们预计整数会更快,情况确实如此:
julia> a = MyType(1)
MyType{Int64}(1)
julia> b = MyType(2)
MyType{Int64}(2)
julia> @btime $a == $b
1.882 ns (0 allocations: 0 bytes)
false但是那样的话API可能就不那么方便了。使用枚举类型可能更易读(用户不必记住哪个值对应于"apple")。它还防止使用未预先定义的任何值,同时保持相同的性能:
julia> @enum Fruit begin
apple
banana
end
julia> a = MyType(apple)
MyType{Fruit}(apple)
julia> b = MyType(banana)
MyType{Fruit}(banana)
julia> @btime $a == $b
1.816 ns (0 allocations: 0 bytes)
false最后一个值得考虑的选择是使用符号作为密钥,这既保留了(IMO)的可使用性,也保留了性能:
julia> a = MyType(:apple)
MyType{Symbol}(:apple)
julia> b = MyType(:banana)
MyType{Symbol}(:banana)
julia> @btime $a == $b
1.883 ns (0 allocations: 0 bytes)
false没有什么可以阻止任何人构建一个非法的值,比如MyStruct(:cheddar),但是它非常适合于字符串被操纵的上下文。例如,如果您在工作流中的某个位置将id作为字符串获得,则在构造MyStruct实例之前,可以轻松地将其转换为符号:
julia> id = "apple"
"apple"
julia> a = MyType(Symbol(id))
MyType{Symbol}(:apple)发布于 2020-03-21 22:03:30
用朱莉娅的打字系统!不需要外部库。
abstract type Fruit end
struct Apple <: Fruit end
struct Banana <: Fruit end
struct Coconut <: Fruit end
struct MyType{T<:Fruit}
#could be some fields here...
end
a = MyType{Apple}()
a2 = MyType{Apple}()
b = MyType{Banana}()这种方法有两个优点:
这只是一个无与伦比的性能基准:
julia> using BenchmarkTools
julia> @btime $a == $b
0.001 ns (0 allocations: 0 bytes)
false
julia> @btime $a == $a2
0.001 ns (0 allocations: 0 bytes)
true编辑
回答@Cameron Bieganek的问题
对于何时手工定义单例类型以及何时使用
Enum更有意义,您有什么意见或指导吗?
我个人的意见如下:
Strings)在运行时生成,并且您计划对它们进行比较,请使用Symbols。很好的例子是解析一个CSV文件,其中列包含标称值。Enums或Symbols --使用代码可读性作为标准。https://stackoverflow.com/questions/60778982
复制相似问题