我目前正在尝试实现一种元启发式(遗传)算法。在这个项目中,我还想尝试创建速度更快、效率更高的代码。然而,我在创建高效编码方面的经验并不是很好。因此,我想知道是否有人能给出一些“快速提示”来提高我的代码效率。我已经创建了我的代码的一个小的函数示例,它包含了代码所包含的大部分元素--我认为这些元素包括预分配数组、自定义可变结构、随机数、推入数组等等。
我已经尝试探索的选项是有关包"StaticArrays“的选项。然而,我的许多数组必须是可变的(因此我们需要MArrays),而且其中许多将变得非常大,超过100。StaticArrays的文档指定StaticArrays包的大小必须保持较小才能保持效率。
根据文档,Julia1.5.2在rand()方面应该是线程安全的。为此,我尝试在我的函数中使用多线程for-循环,以使它们运行得更快。这导致性能略有提高。
但是,如果人们能够采用更有效的方式分配数组或将SpotPrices推入数组中,那将是非常感谢的!任何其他性能提示也非常欢迎!
# Packages
clearconsole()
using DataFrames
using Random
using BenchmarkTools
Random.seed!(42)
df = DataFrame( SpotPrice = convert(Array{Float64}, rand(-266:500,8832)),
month = repeat([1,2,3,4,5,6,7,8,9,10,11,12]; outer = 736),
hour = repeat([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]; outer = 368))
# Data structure for the prices per hour
mutable struct SpotPrices
hour :: Array{Float64,1}
end
# Fill-out data structure
function setup_prices(df::DataFrame)
prices = []
for i in 1:length(unique(df[:,3]))
push!(prices, SpotPrices(filter(row -> row.hour == i, df).SpotPrice))
end
return prices
end
prices = setup_prices(df)
# Sampler function
function MC_Sampler(prices::Vector{Any}, sample_size::Int64)
# Picking the samples
tmp = zeros(sample_size, 24)
# Sampling per hour
for i in 1:24
tmp[:,i] = rand(prices[i].hour, sample_size)
end
return tmp
end
samples = MC_Sampler(prices, 100)
@btime setup_prices(df)
@btime MC_Sampler(prices,100)
function setup_prices_par(df::DataFrame)
prices = []
@sync Threads.@threads for i in 1:length(unique(df[:,3]))
push!(prices, SpotPrices(filter(row -> row.hour == i, df).SpotPrice))
end
return prices
end
# Sampler function
function MC_Sampler_par(prices::Vector{Any}, sample_size::Int64)
# Picking the samples
tmp = zeros(sample_size, 24)
# Sampling per hour
@sync Threads.@threads for i in 1:24
tmp[:,i] = rand(prices[i].hour, sample_size)
end
return tmp
end
@btime setup_prices_par(df)
@btime MC_Sampler_par(prices,100)发布于 2020-11-15 15:27:59
仔细阅读https://docs.julialang.org/en/v1/manual/performance-tips/
基本清理工作从以下几个方面开始:
SpotPrices struct对我来说不需要可变。无论如何,由于只有一个字段,所以您只需将其定义为SpotPrices=Vector{Float64}prices = [] do,prices = Float64[]DataFrames.groupby将比查找唯一元素和过滤它们快得多--如果您不需要初始化,那么Vector{Float64}(undef, sample_size)比zeros(sample_size, 24)@sync的速度要快得多--每个线程都要单独使用一个状态,并且每当调用rand函数h 223g 224时,使用它们的速度要快得多。https://stackoverflow.com/questions/64845551
复制相似问题