Hello, welcome to the Julia community.
To be upfront: this question is pretty hard to answer comprehensively. If you have a specific application in mind, it would be better to present your problem and ideas and ask for opinions here.
In most cases, there is not a single correct way to do things¹.
If you meant to pose this as a general question, then take some of my considerations. (no guarantee for correctness, objectivity and especially not completeness):
All depends on what you want to do with it. Tuples are great and efficient if you want to structure a fixed (smallish) amount of objects. Bonus points if the types rarely change. NamedTuples are the convenience version. StaticArrays
can lift a lot of the benefits of Tuples to the Array space.
(Immutable) Structs should be preferred over tuples for abstraction reasons or dispatch. That is, if it makes sense that your collection of a fixed number of things equates to some atomic concept in whatever you plan to do, making a struct makes sense. The other reason for structs is dispatch. So if you need to specialize the behavior of something on exactly your structure, then creating (at least wrapper) types makes sense.
Immutable to mutable struct is more of a gradient than a clear cut. You can make single fields of an immutable struct mutable via Ref
, so if you group a lot of truly immutable things with a single mutable one, you need not make the entire structure mutable. Likewise, if you expect changes to be rare, you can handle mutations of immutable structs as copy-and-change if you adapt your handling accordingly. If changes are frequent, you should use mutable structs or at least mutable fields (mutable objects in an immutable struct are still mutable). You can even abstract away your decision entirely with Setfield.jl
or its successors.
If you need a dictionary or not is, uhm, well, you will know if you need one yourself. Dictionaries are mappings, that’s it. Performance wise, performance depends on the implementation. Normal dictionaries have the usual performance implications of hashmaps, i.e. the need to hash and compare things. If hashing is expensive (or you typically store few things), you can use hashing-free implementations like LittleDict
, but determining the performance cutoff in your specific application is usually only possible empirically.
Care must be taken if you want to use mutable things as keys. Other languages disallow this entirely, Julia lets you use whatever you fancy, but mutating keys will break the normal dictionaries, but there are ways around that if you care.
I’ll let out dataframes because this is already long enough. DataFrames are for tabular data, pretty mature and efficient for that matter. Be aware that tabular here means columns are first class and rows not (not named). There’s probably yet a better structure for cases with named rows and columns.
[¹]: This is true for many languages, but many have strong support for one or the other approach, while you are often enough different approaches work equally well in Julia.
Take away: It depends, if you want to do anything particular, just ask
Edit 2: I didn’t even came to mention Arrays, gaah, the arrays. There’s literally dozens of different array-like things with different foci. StaticArrays
, ComponentArrays
, ElasticArrays
, regular Arrays
. It really depends on your use case. In general, Arrays provide a convenient abstraction for discernible dimensions in data and a way to allow varying number of elements (with plain arrays only for one-dimensional arrays, but other implementations can grow even in higher dimensions, e.g. ElasticArrays
)