Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Funktionale Parallelität in Scala
Search
Tobias Neef
June 13, 2013
Programming
71
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Funktionale Parallelität in Scala
Tobias Neef
June 13, 2013
More Decks by Tobias Neef
See All by Tobias Neef
One night at a METRO depot
tobnee
0
96
Reactive Play and Scala
tobnee
1
280
Behavioural Abstractions in Play
tobnee
0
160
Functional Parallel Architecture
tobnee
1
110
OO in Scala - The unloved side of the cake?
tobnee
2
140
Play Techtalk - Async Play
tobnee
2
520
Other Decks in Programming
See All in Programming
SlackアプリとLambdaの 連携を構築した話
pawn_4_s
1
120
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
180
FDEが実現するAI駆動経営の現在地
gonta
2
280
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
500
リアルな遅延を測る仕様
kota_yata
1
110
Built Our Own Background Agent at LayerX
layerx
PRO
10
5.6k
php-fpmのプロセスが枯渇した日-調査・対処・そして本当にやるべきだったこと-
shibuchaaaan
0
300
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
540
運用ダッシュボードの設計を誰も教えてくれないのだけどみなさんどうしてるんですか? - チームに監視するという文化を根付かせるための第一歩を踏みたい -
satoshi256kbyte
1
120
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
120
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
190
Go 1.27 における memory allocation の高速化
andpad
0
190
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
7k
Facilitating Awesome Meetings
lara
57
7.1k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
380
The untapped power of vector embeddings
frankvandijk
2
1.8k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
410
Large-scale JavaScript Application Architecture
addyosmani
515
110k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Git: the NoSQL Database
bkeepers
PRO
432
67k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Embracing the Ebb and Flow
colly
88
5.1k
Scaling GitHub
holman
464
140k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
270
Transcript
Funktionale Parallelität in Scala
Procedural Parallelism vs. Functional Parallelism
How vs. What
A uniform API for parallelism
map / / transform from a -> b flatMap /
/ transform a -> a1..ax filter / / only use certain values zip / / combine computations reduce / / transform a1..ax -> b
Divide and Conquer
Parallel Sum
Technical View
Slice P P P W W
API View
def sum(numbers:Seq[Long]) = numbers.reduce(_+_)
A Scala ForkJoin Interface
def sum(numbers:Seq[Long]) = numbers.par.reduce(_+_)
Async IO Processing
Reduce Blocking -> Increase parallelism
None
0 20 40 60 80 Deal2 Deal1 Deal5 Deal4 Deal3
Deals Berlin
None
App Index Page Deal 1 Deal 2 Deal X HTML
Parser Output Gen
App Index Get D1 Get D2 Get DX Result Parse
D1 Parse D2 Parse DX Merge Time
Futures
java.util.concurrent
None
None
scala.concurrent
map flatMap filter forEach zip andThen ...
val f = for { a ˡ Future(10 / 2)
/ / 10 / 2 = 5 b ˡ Future(a + 1) / / 5 + 1 = 6 c ˡ Future(a - 1) / / 5 - 1 = 4 if c > 3 } yield b * c
Back to the example
App Index Get D1 Get D2 Get DX Result Parse
D1 Parse D2 Parse DX Merge Time
A chain of dependent operations happening in the future
def dealOverviewData(city: String) = for { links <-
dealLinksForCity(city) dealPriceAndDiscounts <- fetchAndExtractDeals(links) if !dealPriceAndDiscounts.isEmpty } yield dealPriceAndDiscounts
App Index Get D1 Get D2 Get DX Result Parse
D1 Parse D2 Parse DX Merge Time
def dealLinksForCity(city: String) = { WS.url(url+city).get() .map(_.body.toString) .map(extractLinks) }
App Index Get D1 Get D2 Get DX Result Parse
D1 Parse D2 Parse DX Merge Time
def dealOverviewData(city: String) = for { links <-
dealLinksForCity(city) dealPriceAndDiscounts <- fetchAndExtractDeals(links) if !dealPriceAndDiscounts.isEmpty } yield dealPriceAndDiscounts “Parallel Looping”
def fetchAndExtractDeals(links:List[String]) = .... links.map(fetchAndExtractDealData) ....
def fetchAndExtractDealData(link: String) = { WS.url(link).get() .map(_.body.toString) .map(extractDealData) }
App Index Get D1 Get D2 Get DX Result Parse
D1 Parse D2 Parse DX Merge Time
def fetchAndExtractDeals(links:List[String]) = Future.sequence( links.map(fetchAndExtractDealData) )
def dealOverviewData(city: String) = for { links <-
dealLinksForCity(city) dealPriceAndDiscounts <- fetchAndExtractDeals(links) if !dealPriceAndDiscounts.isEmpty } yield dealPriceAndDiscounts
https:/ /github.com/ tobnee/play-async-ws- demo
Parallel (Distributed) Batch Processing
MapReduce
map (k1,v1) ˠ list(k2,v2) reduce (k2,list(v2)) ˠ list(v3)
Distributed WordCount http:/ /commons.wikimedia.org/wiki/File:Rosetta_Stone.JPG
map(String key, String value): for each word w in value:
EmitIntermediate(w, "1");
reduce(String key, Iterator values): int result = 0; for each
v in values: result += ParseInt(v); Emit(AsString(result));
http:/ /de.wikipedia.org/wiki/Datei:Mapreduce_(Ville_Tuulos).png
Lets get real
1 package org.myorg; 2 3 import java.io.IOException; 4 import java.util.*;
5 6 import org.apache.hadoop.fs.Path; 7 import org.apache.hadoop.conf.*; 8 import org.apache.hadoop.io.*; 9 import org.apache.hadoop.mapreduce.*; 10 import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 11 import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 12 import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 13 import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; 14 15 public class WordCount { 16 17 public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> { 18 private final static IntWritable one = new IntWritable(1); 19 private Text word = new Text(); 20 21 public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { 22 String line = value.toString(); 23 StringTokenizer tokenizer = new StringTokenizer(line); 24 while (tokenizer.hasMoreTokens()) { 25 word.set(tokenizer.nextToken()); 26 context.write(word, one); 27 } 28 } 29 } 30 31 public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> { 32 33 public void reduce(Text key, Iterable<IntWritable> values, Context context) 34 throws IOException, InterruptedException { 35 int sum = 0; 36 for (IntWritable val : values) { 37 sum += val.get(); 38 } 39 context.write(key, new IntWritable(sum)); 40 } 41 } 42 43 public static void main(String[] args) throws Exception { 44 Configuration conf = new Configuration(); 45 46 Job job = new Job(conf, "wordcount"); 47 48 job.setOutputKeyClass(Text.class); 49 job.setOutputValueClass(IntWritable.class); 50 51 job.setMapperClass(Map.class); 52 job.setReducerClass(Reduce.class); 53 54 job.setInputFormatClass(TextInputFormat.class); 55 job.setOutputFormatClass(TextOutputFormat.class); 56 57 FileInputFormat.addInputPath(job, new Path(args[0])); 58 FileOutputFormat.setOutputPath(job, new Path(args[1])); 59 60 job.waitForCompletion(true); 61 } 62 63 }
FP equivalent in Scala
val lines = fromTextFile("hdfs:/ /in/...") ! val counts = lines.flatMap(line
=> line.split(" ")) .map(word => (word, 1)) .groupByKey .combine(_+_) ! persist(counts.toTextFile("hdfs:/ /out/...", overwrite=true))
We have seen classic examples of parallel computations MapReduce ForkJoin
Async Workflows
Some of these concepts can be expressed in a uniform,
monadic way This style of programming is well suited for functional languages like Scala, Haskell, Clojure or F#