Vector of tuples vs Matrix type

I’m pretty new to Julia and was wondering what the preferred practice for storing something like a bunch of coordinates, mesh triangles or graph edges?

Say I want to store edges in a graph. The vertices are labelled by indices 1,2,3,…
Would I want to be storing the edges as 2-tuples in a Vector{Tuple{Int, Int}}, since I know that each edge is stored as exactly 2 vertex indices?
Or would it be better to store the edges in a 2-by-N matrix structure Matrix{Int} (each edge stored as a column, since afaik looping over columns is preferred over rows)?
Or is there a third way I don’t know of which is better than both of the above?

These in fact have the same storage, so you can use either and convert for free. A third option would be StaticArrays, which are essentially tuples wrapped up to look like vectors:

julia> mat = rand(1:99, 2,3)
2×3 Matrix{Int64}:
 19   7   4
  9  11  52

julia> reinterpret(reshape, Tuple{Int,Int}, mat) # with Julia 1.6, or Compat.jl
3-element reinterpret(reshape, Tuple{Int64, Int64}, ::Matrix{Int64}) with eltype Tuple{Int64, Int64}:
 (19, 9)
 (7, 11)
 (4, 52)

julia> using StaticArrays

julia> svecs = [SVector(rand(1:99), rand(1:99)) for _ in 1:3]
3-element Vector{SVector{2, Int64}}:
 [7, 17]
 [11, 36]
 [69, 80]

julia> reshape(reinterpret(Int, svecs),2,:) # works on Julia <= 1.5 too
2×3 reshape(reinterpret(Int64, ::Vector{SVector{2, Int64}}), 2, 3) with eltype Int64:
  7  11  69
 17  36  80
6 Likes

What the best solution is, depends on what you want to do. If you intend to do a lot of operations on the 2-vectors, then a vector of StaticVectors could be very advantageous. If you are doing ordinary matrix operations, then a matrix is probably better.

In addition to what @mcabbott suggested, you have a fourth option: https://github.com/mateuszbaran/HybridArrays.jl which try to combine the advantages of both approaches. I haven’t tried it, though.

4 Likes