Effective Solution for transformation Matrix to Vector {Block}

question
performance
benchmark

#1

Hello, I have an exciting problem. Consider type Block and rawData Matrix.

struct Block
  name::String
  data::Vector{Float64}
end
headers = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
rawData = rand(8700, 10)
dataRanges = Vector{UnitRange}([1:400, 500:8000])

Now we want to transform Matrix into Vector{Block} with using data ranges. My naive solution is:

function fNaive(rawData::Matrix{Float64}, dataRanges::Vector{UnitRange})
  db = map(1:cols(rawData)) do i
    map(r -> Block(headers[i], view(rawData, r, i)), dataRanges)
  end
  
  vcat(db...)
end

How to get the most effective solution for Vector{Block}, any solution?
Thanks


For better imagination, one block is a one-color of the Matrix.


#2

I get the impression that this is a very effective solution. I’ve replaced the nested function map with comprehension, which gives a little better results.


#3

Ou, I forgot to add cols function, but that could be clearly.

cols(X::Array) = size(X, 2)


#4

Depends on what you mean by “effective”. It is probably not the most efficient solution because of the extra arrays and copies via vcat. I would just tend to do something like:

v = Block[]
for i in 1:size(rawData,2), r in dataRanges
    push!(v, Block(headers[i], view(rawData, r, i)))
end
return v

which is both shorter and more efficient.

(Coming from other languages, people are often afraid to write loops. Sometimes explicit loops are the clearest code, and they are often the most efficient too!)