- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个程序,其中 main()
函数采用四个参数。当我在函数上运行 @code_warntype 时,似乎没有什么问题。所有变量都指定了类型,并且没有 UNION
实例或其他明显的警告标志。
抱歉,该程序相当长,但我不知道如何在保留问题的同时缩短它:
function main(n::Int, dice::Int=6, start::Int=1, modal::Int=3) ::Tuple{String, Vector{String}, Vector{Float64}}
board = String["GO", "A1", "CC1", "A2", "T1", "R1", "B1", "CH1", "B2", "B3",
"JAIL", "C1", "U1", "C2", "C3", "R2", "D1", "CC2", "D2", "D3",
"FP", "E1", "CH2", "E2", "E3", "R3", "F1", "F2", "U2", "F3",
"G2J", "G1", "G2", "CC3", "G3", "R4", "CH3", "H1", "T2", "H2"]
cc_cards = shuffle(collect(1:16))
ch_cards = shuffle(collect(1:16))
function take_cc_card(square::Int, cards::Vector{Int})::Tuple{Int, Vector{Int}}
if cards[1] == 1
square = findfirst(board, "GO")
elseif cards[1] == 2
square = findfirst(board, "JAIL")
end
p = pop!(cards)
unshift!(cards, p)
return square, cards
end
function take_ch_card(square::Int, cards::Vector{Int})::Tuple{Int, Vector{Int}}
if cards[1] == 1
square = findfirst(board, "GO")
elseif cards[1] == 2
square = findfirst(board, "JAIL")
elseif cards[1] == 3
square = findfirst(board, "C1")
elseif cards[1] == 4
square = findfirst(board, "E3")
elseif cards[1] == 5
square = findfirst(board, "H2")
elseif cards[1] == 6
square = findfirst(board, "R1")
elseif cards[1] == 7 || cards[1] == 8
if board[square] == "CH1"
square = findfirst(board, "R2")
elseif board[square] == "CH2"
square = findfirst(board, "R3")
elseif board[square] == "CH3"
square = findfirst(board, "R1")
end
elseif cards[1] == 9
if board[square] == "CH1"
square = findfirst(board, "U1")
elseif board[square] == "CH2"
square = findfirst(board, "U2")
elseif board[square] == "CH3"
square = findfirst(board, "U1")
end
elseif cards[1] == 10
square = (square - 3) % 40 + ((square - 3 % 40 == 0 ? 40 : 0))
end
p = pop!(cards)
unshift!(cards, p)
return square, cards
end
result = zeros(Int, 40)
consec_doubles = 0
square = 1
for i = 1:n
throw_1 = rand(collect(1:dice))
throw_2 = rand(collect(1:dice))
if throw_1 == throw_2
consec_doubles += 1
else
consec_doubles = 0
end
if consec_doubles != 3
move = throw_1 + throw_2
square = (square + move) % 40 +((square + move) % 40 == 0 ? 40 : 0)
if board[square] == "G2J"
square = findfirst(board, "JAIL")
elseif board[square][1:2] == "CC"
square, cc_cards = take_cc_card(square, cc_cards)
elseif board[square][1:2] == "CH"
square, ch_cards = take_ch_card(square, ch_cards)
if board[square][1:2] == "CC"
square, cc_cards = take_cc_card(square, cc_cards)
end
end
else
square = findfirst(board, "JAIL")
consec_doubles = 0
end
if i >= start
result[square] += 1
end
end
result_tuple = Vector{Tuple{Float64, Int}}()
for i = 1:40
percent = result[i] * 100 / sum(result)
push!(result_tuple, (percent, i))
end
sort!(result_tuple, lt = (x, y) -> isless(x[1], y[1]), rev=true)
modal_squares = Vector{String}()
modal_string = ""
modal_percents = Vector{Float64}()
for i = 1:modal
push!(modal_squares, board[result_tuple[i][2]])
push!(modal_percents, result_tuple[i][1])
k = result_tuple[i][2] - 1
modal_string *= (k < 10 ? ("0" * string(k)) : string(k))
end
return modal_string, modal_squares, modal_percents
end
@code_warntype main(1_000_000, 4, 101, 5)
但是,当我通过在第一个参数后面插入分号而不是逗号来将最后三个参数更改为关键字时...
function main(n::Int; dice::Int=6, start::Int=1, modal::Int=3) ::Tuple{String, Vector{String}, Vector{Float64}}
...我似乎遇到了类型稳定性问题。
@code_warntype main(1_000_000, dice=4, start=101, modal=5)
现在,当我运行 @code_warntype
时,我在正文中获得了一个具有 ANY
类型的临时变量和一个 UNION
实例.
奇怪的是,这似乎并没有对性能造成影响,因为在三个基准测试中,“参数”版本的平均运行时间为 431.594 毫秒,而“关键字”版本的运行时间为 413.149 毫秒。不过,我很想知道:
(a) 为什么会发生这种情况;
(b) 作为一般规则,ANY
类型的临时变量的出现是否值得关注;和
(c) 作为一般规则,从性能角度来看,使用关键字而不是普通函数参数是否有任何优势。
最佳答案
这是我对这三个问题的看法。在答案中,我假设 Julia 0.6.3,除非我在帖子末尾明确声明我指的是 Julia 0.7。
(a) 带有 Any
变量的代码是负责处理关键字参数的代码的一部分(例如,确保函数签名允许传递的关键字参数)。原因是关键字参数在函数内以 Vector{Any}
形式接收。该向量保存元组([参数名称], [参数值])
。函数所做的实际“工作”发生在使用 Any
变量的这部分之后。
您可以通过比较调用来看到这一点:
@code_warntype main(1_000_000, dice=4, start=101, modal=5)
和
@code_warntype main(1_000_000)
对于带有关键字参数的函数。第二次调用仅包含上面第一次调用生成的最后一行报告,所有其他调用都负责处理传递的关键字参数。
(b) 作为一般规则,这当然可能是一个问题,但在这种情况下这是无济于事的。具有 Any
的变量保存有关关键字参数名称的信息。
(c) 一般来说,您可以假设位置参数并不比关键字参数慢,但可以更快。这是一个 MWE(实际上,如果您运行 @code_warntype f(a=10)
,您也会看到这个 Any
变量):
julia> using BenchmarkTools
julia> f(;a::Int=1) = a+1
f (generic function with 1 method)
julia> g(a::Int=1) = a+1
g (generic function with 2 methods)
julia> @benchmark f()
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.865 ns (0.00% GC)
median time: 1.866 ns (0.00% GC)
mean time: 1.974 ns (0.00% GC)
maximum time: 14.463 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 1000
julia> @benchmark f(a=10)
BenchmarkTools.Trial:
memory estimate: 96 bytes
allocs estimate: 1
--------------
minimum time: 52.994 ns (0.00% GC)
median time: 54.413 ns (0.00% GC)
mean time: 65.207 ns (10.65% GC)
maximum time: 3.466 μs (94.78% GC)
--------------
samples: 10000
evals/sample: 986
julia> @benchmark g()
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.865 ns (0.00% GC)
median time: 1.866 ns (0.00% GC)
mean time: 1.954 ns (0.00% GC)
maximum time: 13.062 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 1000
julia> @benchmark g(10)
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.865 ns (0.00% GC)
median time: 1.866 ns (0.00% GC)
mean time: 1.949 ns (0.00% GC)
maximum time: 13.063 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 1000
现在你可以看到,实际上关键字参数的惩罚是在它被传递时(当你在 @code_warntype
中有 Any
变量作为 Julia 时,情况正是如此那么必须做更多的工作)。请注意,惩罚很小,并且在执行很少工作的函数中是可见的。对于进行大量计算的函数,大多数时候可以忽略它。
另外请注意,如果您不指定关键字参数的类型,那么在显式传递关键字参数值时,惩罚会更大,因为 Julia 不会分派(dispatch)关键字参数类型(您也可以运行 @code_warntype
见证这一点):
julia> h(;a=1) = a+1
h (generic function with 1 method)
julia> @benchmark h()
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.865 ns (0.00% GC)
median time: 1.866 ns (0.00% GC)
mean time: 1.960 ns (0.00% GC)
maximum time: 13.996 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 1000
julia> @benchmark h(a=10)
BenchmarkTools.Trial:
memory estimate: 96 bytes
allocs estimate: 1
--------------
minimum time: 75.433 ns (0.00% GC)
median time: 77.355 ns (0.00% GC)
mean time: 89.037 ns (7.87% GC)
maximum time: 2.128 μs (89.73% GC)
--------------
samples: 10000
evals/sample: 971
在 Julia 0.7 中,关键字参数作为包含 NamedTuple
的 Base.Iterator.Pairs 接收,因此 Julia 在编译时知道传递参数的类型。这意味着使用关键字参数比 Julia 0.6.3 更快(但同样,您不应该期望它们比位置参数更快)。你可以看到这个购买运行了类似的基准测试(我只是稍微改变了函数的作用,以便为 Julia 编译器提供更多的工作),但在 Julia 0.7 下(你也可以看看 @code_warntype
在这些函数上可以看到类型推断在 Julia 0.7 中效果更好):
julia> using BenchmarkTools
julia> f(;a::Int=1) = [a]
f (generic function with 1 method)
julia> g(a::Int=1) = [a]
g (generic function with 2 methods)
julia> h(;a=1) = [a]
h (generic function with 1 method)
julia> @benchmark f()
BenchmarkTools.Trial:
memory estimate: 96 bytes
allocs estimate: 1
--------------
minimum time: 31.724 ns (0.00% GC)
median time: 34.523 ns (0.00% GC)
mean time: 50.576 ns (22.80% GC)
maximum time: 53.465 μs (99.89% GC)
--------------
samples: 10000
evals/sample: 1000
julia> @benchmark f(a=10)
BenchmarkTools.Trial:
memory estimate: 96 bytes
allocs estimate: 1
--------------
minimum time: 31.724 ns (0.00% GC)
median time: 34.057 ns (0.00% GC)
mean time: 50.739 ns (22.83% GC)
maximum time: 55.303 μs (99.89% GC)
--------------
samples: 10000
evals/sample: 1000
julia> @benchmark g()
BenchmarkTools.Trial:
memory estimate: 96 bytes
allocs estimate: 1
--------------
minimum time: 31.724 ns (0.00% GC)
median time: 34.523 ns (0.00% GC)
mean time: 50.529 ns (22.77% GC)
maximum time: 54.501 μs (99.89% GC)
--------------
samples: 10000
evals/sample: 1000
julia> @benchmark g(10)
BenchmarkTools.Trial:
memory estimate: 96 bytes
allocs estimate: 1
--------------
minimum time: 31.724 ns (0.00% GC)
median time: 34.523 ns (0.00% GC)
mean time: 50.899 ns (23.27% GC)
maximum time: 56.246 μs (99.90% GC)
--------------
samples: 10000
evals/sample: 1000
julia> @benchmark h()
BenchmarkTools.Trial:
memory estimate: 96 bytes
allocs estimate: 1
--------------
minimum time: 31.257 ns (0.00% GC)
median time: 34.057 ns (0.00% GC)
mean time: 50.924 ns (22.87% GC)
maximum time: 55.724 μs (99.88% GC)
--------------
samples: 10000
evals/sample: 1000
julia> @benchmark h(a=10)
BenchmarkTools.Trial:
memory estimate: 96 bytes
allocs estimate: 1
--------------
minimum time: 31.724 ns (0.00% GC)
median time: 34.057 ns (0.00% GC)
mean time: 50.864 ns (22.60% GC)
maximum time: 53.389 μs (99.83% GC)
--------------
samples: 10000
evals/sample: 1000
关于julia - 在 Julia 中将函数参数更改为关键字似乎会引入类型不稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51114781/
我正在尝试编写一个相当多态的库。我遇到了一种更容易表现出来却很难说出来的情况。它看起来有点像这样: {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE
谁能解释一下这个表达式是如何工作的? type = type || 'any'; 这是否意味着如果类型未定义则使用“任意”? 最佳答案 如果 type 为“falsy”(即 false,或 undef
我有一个界面,在IAnimal.fs中, namespace Kingdom type IAnimal = abstract member Eat : Food -> unit 以及另一个成功
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
在 C# 中,default(Nullable) 之间有区别吗? (或 default(long?) )和 default(long) ? Long只是一个例子,它可以是任何其他struct类型。 最
假设我有一个案例类: case class Foo(num: Int, str: String, bool: Boolean) 现在我还有一个简单的包装器: sealed trait Wrapper[
这个问题在这里已经有了答案: Create C# delegate type with ref parameter at runtime (1 个回答) 关闭 2 年前。 为了即时创建委托(dele
我正在尝试获取图像的 dct。一开始我遇到了错误 The function/feature is not implemented (Odd-size DCT's are not implemented
我正在尝试使用 AFNetworking 的 AFPropertyListRequestOperation,但是当我尝试下载它时,出现错误 预期的内容类型{( “应用程序/x-plist” )}, 得
我在下面收到错误。我知道这段代码的意思,但我不知道界面应该是什么样子: Element implicitly has an 'any' type because index expression is
我尝试将 SignalType 从 ReactiveCocoa 扩展为自定义 ErrorType,代码如下所示 enum MyError: ErrorType { // .. cases }
我无法在任何其他问题中找到答案。假设我有一个抽象父类(super class) Abstract0,它有两个子类 Concrete1 和 Concrete1。我希望能够在 Abstract0 中定义类
我想知道为什么这个索引没有用在 RANGE 类型中,而是用在 INDEX 中: 索引: CREATE INDEX myindex ON orders(order_date); 查询: EXPLAIN
我正在使用 RxJava,现在我尝试通过提供 lambda 来订阅可观察对象: observableProvider.stringForKey(CURRENT_DELETED_ID) .sub
我已经尝试了几乎所有解决问题的方法,其中包括。为 提供类型使用app.use(express.static('public'))还有更多,但我似乎无法为此找到解决方案。 index.js : imp
以下哪个 CSS 选择器更快? input[type="submit"] { /* styles */ } 或 [type="submit"] { /* styles */ } 只是好
我不知道这个设置有什么问题,我在 IDEA 中获得了所有注释(@Controller、@Repository、@Service),它在行号左侧显示 bean,然后转到该 bean。 这是错误: 14-
我听从了建议 registering java function as a callback in C function并且可以使用“简单”类型(例如整数和字符串)进行回调,例如: jstring j
有一些 java 类,加载到 Oracle 数据库(版本 11g)和 pl/sql 函数包装器: create or replace function getDataFromJava( in_uLis
我已经从 David Walsh 的 css 动画回调中获取代码并将其修改为 TypeScript。但是,我收到一个错误,我不知道为什么: interface IBrowserPrefix { [
我是一名优秀的程序员,十分优秀!