Maxximiliann

Maxximiliann

Using concurrency to quickly collate data from multiple sources

Given-

Vehicles is a list of 50 VIN numbers (vin_number).

Colors, Makes, Models, Transmissions, Fuel_economy, Horsepower and Torques are each a list of 50 VIN numbers with their respective features.

For instance:

Colors = [%{vin_number: 5YJSA1DG9DFP14705, color: Black} ...]
Makes = [%{vin_number: 5YJSA1DG9DFP14705, make: DB8 GT} ...]

get_colors, get_makes, get_models, get_transmissions, get_fuel_economy, get_horsepower and get_torques are functions which get the respective colors, makes, models, etc., etc., for a particular vin_number.

Example:

def get_colors(vin_number) do 
	Enum.find(Colors, &(&1).vin_number == vin_number)
	|> Map.get(:color)  
end

Collating all of this data into a new map, super_cars, by vin_number-

def super_cars do	
	Enum.map(vehicles, &
		%{
			vin: (&1).vin_number,
			color: get_colors((&1).vin_number)
			make: get_makes((&1).vin_number) 
			model: get_models((&1).vin_number)
			transmission: get_transmissions((&1).vin_number)
			fuel_economy: get_fuel_economy((&1).vin_number)
			horsepower: get_horsepwer((&1).vin_number)
			torque: get_torques((&1).vin_number)
		} 
		)
	end

So here’s my question:

How can Task.async be utilized to optimize the time it takes to create the new super_cars map? (Is there perhaps a better approach? Ecto, maybe?)

As always, thanks for your generous and patient insights :slight_smile:

Most Liked

al2o3cr

al2o3cr

This isn’t directly relevant to your question about using parallelism, but if you’re concerned about performance consider converting your lists into maps:

colors = [%{vin_number: 5YJSA1DG9DFP14705, color: Black} ...]

map_colors = Map.new(colors, fn c -> {c.vin_number, c} end)

Then a function like get_colors is a map lookup, not a linear search.

chrisjowen

chrisjowen

No worries, and although I am not convinced you will need such things for this (I could be wrong just not enough info) I think its worth pointing out your options if you do need to look at parallel processing in Elixir

Firstly all abstractions including Task.async all live on top of the core process model of beam, and its really worth your time understanding this fully.

The next stage is to understand about GenServers and how they encapsulate generic process behaviour (https://hexdocs.pm/elixir/GenServer.html)

After this you may want to still use Task.async or maybe https://hexdocs.pm/elixir/Task.html#async_stream/3

If this is not enough for you then the excellent GenStage (https://hexdocs.pm/gen_stage/GenStage.html) gives you some real control when producing/consuming large datasets.

Finally, there are interesting abstractions above GenStage such as:

Basically there are a lot of ways to do concurrent data processing in Elixir :slight_smile:

chrisjowen

chrisjowen

Maybe, as mentioned there are other overheads in concurrency. If you only have 50 records the question is how many records would each async task process. If you process say 1 item per task it may work out slower than the single process call.

The only way to tell is to try this with different configurations. My gut is that you would be better off keeping this as a single process call and doing smaller optimisations like I mentioned ( @al2o3cr just showed what I mean in their answer, keying by vin number will reduce your lookup time).

LostKobrakai

LostKobrakai

Depending on how you source the data you might be able to parallelize data gathering by putting the source data into an ETS table with read concurrency. So you don’t need to copy the source data, but parallelize the querying part.

chasers

chasers

Yeah I mean I assume these are all in a database somewhere so I’d focus on making a process for each attribute which independently caches those locally in ETS periodically. And then just lookup the vin in ETS when you need it. If not ETS even just consolidating them in a single Postgres table…

Where Next?

Popular in Questions Top

bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New

We're in Beta

About us Mission Statement