SlideShare une entreprise Scribd logo
1  sur  132
Télécharger pour lire hors ligne
@Alex_Victoor @ThierryAbalea#sginsideit
Un  monde  où  1ms  vaut  100M  d’euros
@YourTwitterHandle#DVXFR14{session  hashtag} @Alex_Victoor @ThierryAbalea#sginsideit
Speakers
Alexandre  Victoor
@Alex_Victoor
Thierry  Abaléa
@ThierryAbalea
5Kstatus updates / Sec
6K
Tweets/ Sec
1,6M
Mails / SEC
40K
Searches / SEC
740K
Messages / SEC
Big Data  !=  Web
5Kstatus updates / Sec
6K
Tweets/ Sec
1,6M
Mails / SEC
40K
Searches / SEC
740K
Messages / SEC
1.1M
US OPTIONS
Trades & quotes / SEC
Big Data  !=  Web
Plus  vite  que  la  lumière
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Latence à tous les
niveaux
APPLICATIF
JVM
OS
RESEAU
DISQUE
CPU
MEMOIRE
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Un Quiz pour s’échauffer
int SIZE  =  1000000;
int NB_ARRAY  =  50;
long[][]  longs  
=  new long[NB_ARRAY][SIZE];
long result =  0;
for (int j=0;  j<SIZE;  j++)
for (int i=0;  i<NB_ARRAY;  i++)
result +=  longs[i][j];
int SIZE  =  1000000;
int NB_ARRAY  =  50;
long[][]  longs  
=  new long[NB_ARRAY][SIZE];
long result =  0;
for (int i=0;  i<NB_ARRAY;  i++)
for (int j=0;  j<SIZE;  j++)
result +=  longs[i][j];
Qui  est  le  plus  rapide  ?
1 2
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Memory Layout
Le premier  programme  est  le  plus  rapide  !
47ms
796ms
m
esurer
Cache L3
Unités d’exécution
Cache L1
Cache L2
Coeur  1
Registres
Cache L1
Cache L2
Coeur  2
Processeur
<  1  ns
~ 1  ns
~ 3  ns
~ 12  ns
Registres
Unités d’exécution
int SIZE  =  1000000;
int NB_ARRAY  =  50;
long[][]  longs  
=  new long[NB_ARRAY][SIZE];
long result =  0;
for (int i=0;  i<NB_ARRAY;  i++)
for (int j=0;  j<SIZE;  j++)
result +=  longs[i][j];
Friendly
int SIZE  =  1000000;
int NB_ARRAY  =  50;
long[][]  longs  
=  new long[NB_ARRAY][SIZE];
long result =  0;
for (int j  =  0;  j<SIZE;j++)
for (int i=0;  i<NB_ARRAY;  i++)
result +=  longs[i][j];
Pas  friendly du  tout
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Mesurer
micro benchmarks
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
OpenJDK JMH
$  mvn archetype:generate
-­DinteractiveMode=false  
-­DarchetypeGroupId=org.openjdk.jmh
-­DarchetypeArtifactId=jmh-­java-­benchmark-­archetype
-­DgroupId=org.sample
-­DartifactId=devoxx-­bench
-­Dversion=1.0
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Mise en situation
La  vente  de  produit  financiers  (avant)
RFQ:  Request For  Quote
API - en direct
CLIENTBANQUE
WEB Marchés
SALES +
Trading
Risk (contrôles)Booking
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Java ?
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Simple pour démarrer ?
Random rand  =  new Random();
IntStream stream =  rand.ints(10 *  1024 *  1024,  0,  2);
Random rand  =  new Random();
IntStream stream =  rand.ints(10 *  1024 *  1024,  0,  2);
int sum =  stream.sum();
Random rand  =  new Random();
IntStream stream =  rand.ints(10 *  1024 *  1024,  0,  2);
int sum =  stream.sum();
int sum =  stream.parallel().sum();
Random rand  =  new Random();
IntStream stream =  rand.ints(10 *  1024 *  1024,  0,  2);
int sum =  stream.sum();
int sum =  stream.parallel().sum();
113  ms
Random rand  =  new Random();
IntStream stream =  rand.ints(10 *  1024 *  1024,  0,  2);
int sum =  stream.sum();
int sum =  stream.parallel().sum(); 1167 ms
157  ms
Première  archi
Event  loop
Première  archi
Event  loopI/O
Première  archi
Event  loop I/OI/O
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Queue
Lock
Nos  heures  de  pointe
Open  &  Close
Coût  du  lock
Appels  système
Coût  du  lock
Changements  de  contexte
Cache L3
Unités d’exécution
Cache L1
Cache L2
Coeur  1
Registres
Cache L1
Cache L2
Coeur  2
Processeur
<  1  ns
~ 1  ns
~ 3  ns
~ 12  ns
Registres
Unités d’exécution
Algorithmes  non  bloquants
Au  moins  un  thread  progresse
Algorithmes  non  bloquants
Pas  de  ‘section  critique’,  locks,  mutexes,  spin-­locks,  …
j.u.c.ConcurrentLinkedQueue
P1
P2
P3
C
Queue  MPSC
P1
P2
P3
C
Queues SPSC
P1
P2
P3
C
Queues SPSC
Single  Writer Principle
Deuxième  archi
I/OI/O
producerIndex =  42
Concurrent  Reading  and Writing,  Leslie  Lamport,  1977
E E null null null null null null null E
offset  =  2
consumerIndex =  39 offset  =  9
Lamport Queue
producerIndex =  42
offset  =  2
consumerIndex =  39
offset  =  9
Lamport Queue
nullnull
E
E
E
nullnull
null
nullnull
Concurrent  Reading  and Writing,  Leslie  Lamport,  1977
import java.util.AbstractQueue;
public final class LamportQueue1<E>  extends AbstractQueue<E>  {
private final E[]  buffer;
private volatile long producerIndex =  0;
private volatile long consumerIndex =  0;
public LamportQueue1(int capacity)  {
buffer  =  (E[])  new Object[capacity];
}
@Override
public int size()  {
return (int)  (producerIndex -­‐ consumerIndex);
}
@Override
public boolean offer(final E  e)  {
if (size()  ==  buffer.length)  {
return false;
}
final int offset  =  (int)(producerIndex %  buffer.length);
buffer[offset]  =  e;
producerIndex++;
return true;
}
@Override
public boolean offer(final E  e)  {
if (size()  ==  buffer.length)  {
return false;
}
final int offset  =  (int)(producerIndex %  buffer.length);
buffer[offset]  =  e;
producerIndex++;
return true;
}
@Override
public boolean offer(final E  e)  {
if (size()  ==  buffer.length)  {
return false;
}
final int offset  =  (int)(producerIndex %  buffer.length);
buffer[offset]  =  e;
producerIndex++;
return true;
}
@Override
public boolean offer(final E  e)  {
if (size()  ==  buffer.length)  {
return false;
}
final int offset  =  (int)(producerIndex %  buffer.length);
buffer[offset]  =  e;
producerIndex++;
return true;
}
@Override
public E  poll()  {
if (consumerIndex ==  producerIndex)  {
return null;
}
final int offset  =  (int)(consumerIndex %  buffer.length);
final E  e  =  buffer[offset];
buffer[offset]  =  null;
consumerIndex++;
return e;
}
@Override
public E  poll()  {
if (consumerIndex ==  producerIndex)  {
return null;
}
final int offset  =  (int)(consumerIndex %  buffer.length);
final E  e  =  buffer[offset];
buffer[offset]  =  null;
consumerIndex++;
return e;
}
@Override
public E  poll()  {
if (consumerIndex ==  producerIndex)  {
return null;
}
final int offset  =  (int)(consumerIndex %  buffer.length);
final E  e  =  buffer[offset];
buffer[offset]  =  null;
consumerIndex++;
return e;
}
@Override
public E  poll()  {
if (consumerIndex ==  producerIndex)  {
return null;
}
final int offset  =  (int)(consumerIndex %  buffer.length);
final E  e  =  buffer[offset];
buffer[offset]  =  null;
consumerIndex++;
return e;
}
@Override
public E  poll()  {
if (consumerIndex ==  producerIndex)  {
return null;
}
final int offset  =  (int)(consumerIndex %  buffer.length);
final E  e  =  buffer[offset];
buffer[offset]  =  null;
consumerIndex++;
return e;
}
@Override
public E  poll()  {
if (consumerIndex ==  producerIndex)  {
return null;
}
final int offset  =  (int)(consumerIndex %  buffer.length);
final E  e  =  buffer[offset];
buffer[offset]  =  null;
consumerIndex++;
return e;
}
,4
,16
,0
,5
,10
,15
,20
BQ LQ1
16
Performance  (MOps/s) x 4
BlockinqQueue Lamport v1
20
15
10
5
0
4
Correct  ?
private final E[]  buffer;
private volatile long producerIndex =  0;
private volatile long consumerIndex =  0;
@Override
public boolean offer(final E  e)  {
if (size()  ==  buffer.length)  {
//  queue  is full
return false;
}
final int offset  =
(int)(producerIndex
%  buffer.length);
buffer[offset]  =  e;
producerIndex++;
return true;
}
@Override
public E  poll()  {
if (consumerIndex ==  producerIndex)  {  
//  queue  is empty
return null;
}
final int offset  =  (int)(consumerIndex
%  buffer.length);
final E  e  =  buffer[offset];
buffer[offset]  =  null;
consumerIndex++;
return e;
}
Producer  Thread Consumer  Thread
//  consumerIndex =  2
//  producerIndex =  2
//  e  =  777
Producer  Thread Consumer  Thread
//  consumerIndex =  2
//  producerIndex =  2
//  e  =  777
final int offset  =
(int)(producerIndex
%  buffer.length);  //  2
Producer  Thread Consumer  Thread
//  consumerIndex =  2
//  producerIndex =  2
//  e  =  777
final int offset  =
(int)(producerIndex
%  buffer.length);  //  2
buffer[offset]  =  e; //  buff[2]  =  777
Producer  Thread Consumer  Thread
//  consumerIndex =  2
//  producerIndex =  2
//  e  =  777
final int offset  =
(int)(producerIndex
%  buffer.length);  //  2
buffer[offset]  =  e; //  buff[2]  =  777
producerIndex++; //  3
Producer  Thread Consumer  Thread
if (consumerIndex ==  producerIndex)  {  //  2  !=  3
//  queue  is  empty  
return null;
}
Producer  Thread Consumer  Thread
//  consumerIndex =  2
//  producerIndex =  2
//  e  =  777
final int offset  =
(int)(producerIndex
%  buffer.length);  //  2
buffer[offset]  =  e; //  buff[2]  =  777
producerIndex++; //  3
if (consumerIndex ==  producerIndex)  {  //  2  !=  3
//  queue  is  empty  
return null;
}
final int offset  =  (int)(consumerIndex
%  buffer.length); //  2  
Producer  Thread Consumer  Thread
//  consumerIndex =  2
//  producerIndex =  2
//  e  =  777
final int offset  =
(int)(producerIndex
%  buffer.length);  //  2
buffer[offset]  =  e; //  buff[2]  =  777
producerIndex++; //  3
if (consumerIndex ==  producerIndex)  {  //  2  !=  3
//  queue  is  empty  
return null;
}
final int offset  =  (int)(consumerIndex
%  buffer.length); //  2  
final E  e  =  buffer[offset]; //  null  (buffer[2])
…
return e; //  return null
Producer  Thread Consumer  Thread
//  consumerIndex =  2
//  producerIndex =  2
//  e  =  777
final int offset  =
(int)(producerIndex
%  buffer.length);  //  2
buffer[offset]  =  e; //  buff[2]  =  777
producerIndex++; //  3
if (consumerIndex ==  producerIndex)  {  //  2  !=  3
//  queue  is  empty  
return null;
}
final int offset  =  (int)(consumerIndex
%  buffer.length); //  2  
final E  e  =  buffer[offset]; //  null  (buffer[2])
…
return e; //  return null
Producer  Thread Consumer  Thread
Java  1.4
//  consumerIndex =  2
//  producerIndex =  2
//  e  =  777
final int offset  =
(int)(producerIndex
%  buffer.length);  //  2
buffer[offset]  =  e; //  buff[2]  =  777
producerIndex++; //  3
if (consumerIndex ==  producerIndex)  {  //  2  !=  3
//  queue  is  empty  
return null;
}
final int offset  =  (int)(consumerIndex
%  buffer.length); //  2  
final E  e  =  buffer[offset]; //  777 (buffer[2])
…
return e; //  return 777
Producer  Thread Consumer  Thread
Java  1.5  &  +
//  consumerIndex =  2
//  producerIndex =  2
//  e  =  777
final int offset  =
(int)(producerIndex
%  buffer.length);  //  2
buffer[offset]  =  e; //  buff[2]  =  777
producerIndex++; //  3
Happens-­Before
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Encore un Quiz !
Lequel  est  le  plus  rapide  ?
public static final int SIZE  =  256 *  1024;
private int[]  data  =  new int[SIZE];
@Setup
public void init()  {
Random rand  =  new Random();
for (int i  =  0;  i  <  SIZE;  i++)  {
data[i]  =  rand.nextInt(100)  -­‐ 50;
}
}
@Benchmark
public int mathAbs()  {
int sum =  0;
for (int x  :  data)  {
sum +=  Math.abs(x);
}
return sum;
}
@Benchmark
public int customAbs()  {
int sum =  0;
for (int x  :  data)  {
if (x  <  0)  {
sum -­‐=  x;
}  else {
sum +=  x;
}
}
return sum;
}
1 2
Lequel  est  le  plus  rapide  ?
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Instruction Pipeline
Le premier  programme  est  le  plus  rapide  !
273us
1180us
m
esurer
Fetch Decode Write-backExecute
Instruction
Instruction
Instruction
Instruction
Waiting
Program  Order Cycle  d’horloge 1
Fetch Decode Write-backExecute
Instruction
Instruction
Instruction
Instruction
Waiting
Program  Order Cycle  d’horloge 2
Fetch Decode Write-backExecute
Instruction
Instruction
Instruction
Instruction
Waiting
Program  Order Cycle  d’horloge 3
Fetch Decode Write-backExecute
Instruction
Instruction
Instruction
Instruction
Waiting
Program  Order Cycle  d’horloge 4
Fetch Decode Write-backExecute
Instruction
Instruction
Instruction
Instruction
Waiting
Cycle  d’horloge 5Program  Order
Fetch Decode Write-backExecute
Instruction
Instruction
Instruction
Waiting
Cycle  d’horloge 6Program  Order
Fetch Decode Write-backExecute
jump if sign
Waiting
Program  Order Cycle  d’horloge 1
Fetch Decode Write-backExecute
jump if sign
Waiting
Program  Order Cycle  d’horloge 2
Fetch Decode Write-backExecute
jump if sign
Waiting
Program  Order Cycle  d’horloge 3
Fetch Decode Write-backExecute
jump if sign
Waiting
Program  Order Cycle  d’horloge 4
Fetch Decode Write-backExecute
jump if sign
Waiting
Program  Order Cycle  d’horloge 4
Poubelle
Bad  Prediction
@YourTwitterHandle#DVXFR14{session  hashtag} @Alex_Victoor @ThierryAbalea#sginsideit
Mesurer la latence
moyenne
4
Latence
Temps
Centile  (percentile)
Latence
Temps
Centile  (percentile)
Latence
Temps
Centile  (percentile)
3.5
50%
Latence
Temps
Centile  (percentile)
3.5
6
50%
90%
Latence
Temps
Centile  (percentile)
HdrHistogram
Histogram histo = new Histogram(5);;
histo.recordValue(end-­start);;
histo.getValueAtPercentile(0.99);;
histo.outputPercentileDistribution(os, 1D);;
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Queue v2
Coût  du  volatile
Unités d’exécution
Cache L1
Cache L2
Coeur
Registres
Store  Buffer
Unités d’exécution
Cache L1
Cache L2
Coeur
Registres
Store  Buffer
Volatile  store
Unités d’exécution
Cache L1
Cache L2
Coeur
Registres
S5
S4
S3
S2
S1
Store  Buffer
Volatile  store
import java.util.AbstractQueue;
public final class LamportQueue2<E>  extends AbstractQueue<E>  {
private final E[]  buffer;
private final AtomicLong producerIndex =  new AtomicLong();
private final AtomicLong consumerIndex =  new AtomicLong();
public LamportQueue2(int capacity)  {
buffer  =  (E[])  new Object[capacity];
}
@Override
public int size()  {
return (int)  (producerIndex.get()  -­‐ consumerIndex.get());
}
@Override
public boolean offer(final E  e)  {
if (size()  ==  buffer.length)  {
return false;
}
final int offset  =  (int)(producerIndex %  buffer.length);
buffer[offset]  =  e;
producerIndex.lazySet(producerIndex.get()  +  1);
return true;
}
@Override
public E  poll()  {
if (consumerIndex ==  producerIndex)  {
return null;
}
final int offset  =  (int)(consumerIndex.get() %  buffer.length);
final E  e  =  buffer[offset];
buffer[offset]  =  null;
consumerIndex.lazySet(consumerIndex.get()  +  1);
return e;
}
Performance  (MOps/s)
,4
,16
,43
,0
,10
,20
,30
,40
,50
BQ LQ1 LQ2
X  10
BlockinqQueue Lamport v1 Lamport v2
50
40
30
20
10
0
4
16
43
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
LES LOGS
Les  logs,  plusieurs  approches
• Appender fichier standard, écritures bloquantes
Les  logs,  plusieurs  approches
• Appender fichier standard, écritures bloquantes
• Appender bufferisé
Les  logs,  plusieurs  approches
• Appender fichier standard, écritures bloquantes
• Appender bufferisé
• Appender asynchrone
Les  logs,  plusieurs  approches
• Appender fichier standard, écritures bloquantes
• Appender bufferisé
• Appender asynchrone
• Appender memory map file
Memory  map file
Mem virtuelle
Memory  map file
Mem virtuelle Mem physique
Memory  map file
Mem virtuelle DisqueMem physique
Logs  &  mmap
MEMOIRE  (OFF  HEAP)
BUFFER
FICHIER
Données vide
Logs  &  mmap
MEMOIRE  (OFF  HEAP)
BUFFER
FICHIER
Données vide
Appel  systèm
e
<configuration>
<appender name = "TXT-­‐CHRONICLE"  
class  =  "net.openhft.chronicle.logger.logback.TextIndexedChronicleAppender">
<path>perf-­‐test-­‐txt-­‐chronicle</path>
</appender>
</configuration>
Chronicle Logback Appender
Texte  vs  Binaire  – données  de  marché
• Code ISIN sur 12 caractères
• Un prix d’achat (bid)
• Un prix de vente (ask)
Isin=FR0000120271    Bid=46.575    Ask=46.590
Texte  vs  Binaire
Isin=FR0000120271 Bid=46.575 Ask=46.590
Texte  (UTF-­8)
49  73  69  6E  3D  46  52  30  
30  30  30  31  32  30  32  37  
31 20  42  69  64  3D  34  36  
2E  35  37  35 20  41  73  6B  
3D  34  36  2E  35  39  30
39 octets
Binaire
46  52  30  30  30  30  31  32  
30  32  37  31 40  47  49  99  
99  99  99  9A 40  47  4B  85  
1E  B8  51  EC
28 octets (20  avec  des  int)
Serialization vs  toString()  
public class  Quote {
String code;
double bid;
double ask;
}
return "Quote {" +
"code='" +  code  +  ''' +
",  bid=" +  bid +
",  ask=" +  ask +
'}';
Serialization vs  toString()  
public class  Quote {
String code;
double bid;
double ask;
}
ByteBuffer buffer  =  
ByteBuffer.allocate(28);
buffer.put(code.getBytes());
buffer.putDouble(bid);
buffer.putDouble(ask);
buffer.flip();
out.write(buffer.array());
<appender name = "TXT-­‐CHRONICLE"  
class  = "net.openhft.chronicle.logger.logback.TextIndexedChronicleAppender">
<path>perf-­‐test-­‐txt-­‐chronicle</path>
</appender>
<appender name = "BIN-­‐CHRONICLE"
class  =  "net.openhft.chronicle.logger.logback.BinaryIndexedChronicleAppender">
<path>perf-­‐test-­‐bin-­‐chronicle</path>
</appender>
Logger en  binaire  avec  Chronicle
logger.info("New  quote  received  -­‐ {}",  quote);
Bench logger
• Log de 100 000 messages de cotation
• Mesure de la latence induite par l’appel au logger
• System Under Test
CPU : 2x (Xeon E5-2630, 2.3GHz – 2.8 GHz, 6 cores)
RAM : 64 GB DDR3 PC10600
HDD : 2x 300GB en RAID1, 10K tr/min, SAS 6 Gb/s, 1 GB cache
Network 1GbE
OS: RHEL 6.4 avec un kernel 2.6.32
FileAppender vs  BinaryIndexedChronicleAppender
1us
5us
2us
10us
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Conclusion
Dernier  Quiz  :  ce  qu’il  faut  retenir…  
C’est  toujours  le  premier  programme  le  plus  rapide
Il  faut se  méfier  de  son  intuition,  en  matière  de  perf,  il  faut  mesurer  !!!
Soyez  curieux,  le  hardware  ce  n’est pas  sale
DÉCOUVREZ TOUTES NOS OFFRES SUR
C A R E E R S . S O C I E T E G E N E R A L E . C O M
@YourTwitterHandle@YourTwitterHandle@Alex_Victoor @ThierryAbalea#sginsideit
Questions ?
@Alex_Victoor @ThierryAbalea#sginsideit
Références
Talk  ”Lock-­free  Algorithms  for  Ultimate  Performance”,  Martin  Thompson
https://yow.eventer.com/yow-­2012-­1012/lock-­free-­algorithms-­for-­ultimate-­performance-­by-­martin-­thompson-­1250
Talk  “Queue  evolution:  from  10M  to  470M  ops/sec“,  Nitsan  Wakart
https://vimeo.com/100197431 /  https://github.com/nitsanw/QueueEvolution
Talk  “How  NOT  to  Measure  Latency”,  Gil  Tene
http://www.infoq.com/presentations/latency-­pitfalls
JMH,  THE  Micro  Benchmark  Tool  for  Java  http://openjdk.java.net/projects/code-­tools/jmh/
HdrHistogram,  THE  Latency  Measurement  &  Plotting  Tool
https://github.com/HdrHistogram/HdrHistogram
Blog  posts  related  to  Mechanical  Sympathy,  Martin  Thompson
http://mechanical-­sympathy.blogspot.com/
Blog  posts  related  to  Java  Performance,  Nitsan Wakart http://psy-­lob-­saw.blogspot.com/
Blog  posts  related  to  Java  Performance,  Peter  Lawrey http://vanillajava.blogspot.com/
Chronicle,  OpenHFT’s Tools  http://openhft.net/
The  “Mechanical  Sympathy”  Forum  https://groups.google.com/forum/#!forum/mechanical-­sympathy
Code  de  cette  présentation https://github.com/ThierryAbalea/high-­performance-­2015-­talk
Slides  de  cette présentation http://www.slideshare.net/ThierryAbalea/un-­monde-­o-­1-­ms-­vaut-­100-­m-­devoxx-­france-­2015
slideshare

Contenu connexe

Tendances

ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321Teddy Hsiung
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and GoEleanor McHugh
 
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonByterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonakaptur
 
Diving into byte code optimization in python
Diving into byte code optimization in python Diving into byte code optimization in python
Diving into byte code optimization in python Chetan Giridhar
 
Highlight Utility Styles
Highlight Utility StylesHighlight Utility Styles
Highlight Utility StylesAngela Byron
 
Implementing Software Machines in Go and C
Implementing Software Machines in Go and CImplementing Software Machines in Go and C
Implementing Software Machines in Go and CEleanor McHugh
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And BeyondMike Fogus
 
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent SevenMike Fogus
 
Python basic
Python basic Python basic
Python basic sewoo lee
 
Feb14 successful development
Feb14 successful developmentFeb14 successful development
Feb14 successful developmentConnor McDonald
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxyginecorehard_by
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009Jordan Baker
 

Tendances (20)

ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
 
Groovy
GroovyGroovy
Groovy
 
Good Code
Good CodeGood Code
Good Code
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and Go
 
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonByterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
 
Diving into byte code optimization in python
Diving into byte code optimization in python Diving into byte code optimization in python
Diving into byte code optimization in python
 
Highlight Utility Styles
Highlight Utility StylesHighlight Utility Styles
Highlight Utility Styles
 
Implementing Software Machines in Go and C
Implementing Software Machines in Go and CImplementing Software Machines in Go and C
Implementing Software Machines in Go and C
 
C++ L05-Functions
C++ L05-FunctionsC++ L05-Functions
C++ L05-Functions
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
 
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent Seven
 
Python basic
Python basic Python basic
Python basic
 
Whispered secrets
Whispered secretsWhispered secrets
Whispered secrets
 
Feb14 successful development
Feb14 successful developmentFeb14 successful development
Feb14 successful development
 
Project in programming
Project in programmingProject in programming
Project in programming
 
System Calls
System CallsSystem Calls
System Calls
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxygine
 
Whispered secrets
Whispered secretsWhispered secrets
Whispered secrets
 
Go a crash course
Go   a crash courseGo   a crash course
Go a crash course
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009
 

En vedette

Konsep ketuhanan
Konsep ketuhananKonsep ketuhanan
Konsep ketuhananhazrinaali
 
nơi nào dịch vụ giúp việc quận 2 tại sài gòn
nơi nào dịch vụ giúp việc quận 2 tại sài gònnơi nào dịch vụ giúp việc quận 2 tại sài gòn
nơi nào dịch vụ giúp việc quận 2 tại sài gònlindsey789
 
อาเซียนกลุ่มnormal
อาเซียนกลุ่มnormalอาเซียนกลุ่มnormal
อาเซียนกลุ่มnormalpanpantanawan
 
Apjee28 2013 art6_81_102
Apjee28 2013 art6_81_102Apjee28 2013 art6_81_102
Apjee28 2013 art6_81_102shangirl
 
nhận làm dịch vụ giúp việc quận 3 tại hồ chí minh
nhận làm dịch vụ giúp việc quận 3 tại hồ chí minhnhận làm dịch vụ giúp việc quận 3 tại hồ chí minh
nhận làm dịch vụ giúp việc quận 3 tại hồ chí minhherma377
 
Débridez les performances de vos applications avec Chronicle Queue
Débridez les performances de vos applications avec Chronicle QueueDébridez les performances de vos applications avec Chronicle Queue
Débridez les performances de vos applications avec Chronicle QueueThierryAbalea
 
Alcoholes 2 reacciones química orgánica
Alcoholes 2 reacciones  química orgánica Alcoholes 2 reacciones  química orgánica
Alcoholes 2 reacciones química orgánica itzamara2090
 

En vedette (10)

Gusmer Job Review
Gusmer Job ReviewGusmer Job Review
Gusmer Job Review
 
My Resume
My ResumeMy Resume
My Resume
 
Konsep ketuhanan
Konsep ketuhananKonsep ketuhanan
Konsep ketuhanan
 
nơi nào dịch vụ giúp việc quận 2 tại sài gòn
nơi nào dịch vụ giúp việc quận 2 tại sài gònnơi nào dịch vụ giúp việc quận 2 tại sài gòn
nơi nào dịch vụ giúp việc quận 2 tại sài gòn
 
อาเซียนกลุ่มnormal
อาเซียนกลุ่มnormalอาเซียนกลุ่มnormal
อาเซียนกลุ่มnormal
 
Apjee28 2013 art6_81_102
Apjee28 2013 art6_81_102Apjee28 2013 art6_81_102
Apjee28 2013 art6_81_102
 
nhận làm dịch vụ giúp việc quận 3 tại hồ chí minh
nhận làm dịch vụ giúp việc quận 3 tại hồ chí minhnhận làm dịch vụ giúp việc quận 3 tại hồ chí minh
nhận làm dịch vụ giúp việc quận 3 tại hồ chí minh
 
Débridez les performances de vos applications avec Chronicle Queue
Débridez les performances de vos applications avec Chronicle QueueDébridez les performances de vos applications avec Chronicle Queue
Débridez les performances de vos applications avec Chronicle Queue
 
Alcoholes 2 reacciones química orgánica
Alcoholes 2 reacciones  química orgánica Alcoholes 2 reacciones  química orgánica
Alcoholes 2 reacciones química orgánica
 
Makalah wirausaha
Makalah wirausahaMakalah wirausaha
Makalah wirausaha
 

Similaire à Un monde où 1 ms vaut 100 M€ - Devoxx France 2015

5 must have patterns for your microservice - techorama
5 must have patterns for your microservice - techorama5 must have patterns for your microservice - techorama
5 must have patterns for your microservice - techoramaAli Kheyrollahi
 
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloadingkinan keshkeh
 
Actor Concurrency
Actor ConcurrencyActor Concurrency
Actor ConcurrencyAlex Miller
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaFrank Lyaruu
 
LSFMM 2019 BPF Observability
LSFMM 2019 BPF ObservabilityLSFMM 2019 BPF Observability
LSFMM 2019 BPF ObservabilityBrendan Gregg
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовYandex
 
#ifndef CRYPTO_HPP#define CRYPTO_HPP#include functional#.docx
#ifndef CRYPTO_HPP#define CRYPTO_HPP#include functional#.docx#ifndef CRYPTO_HPP#define CRYPTO_HPP#include functional#.docx
#ifndef CRYPTO_HPP#define CRYPTO_HPP#include functional#.docxgertrudebellgrove
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Yandex
 
Zn task - defcon russia 20
Zn task  - defcon russia 20Zn task  - defcon russia 20
Zn task - defcon russia 20DefconRussia
 
How to stop debugging asynchronous code and start living, Andrey Salomatin, B...
How to stop debugging asynchronous code and start living, Andrey Salomatin, B...How to stop debugging asynchronous code and start living, Andrey Salomatin, B...
How to stop debugging asynchronous code and start living, Andrey Salomatin, B...MoscowJS
 
streamparse and pystorm: simple reliable parallel processing with storm
streamparse and pystorm: simple reliable parallel processing with stormstreamparse and pystorm: simple reliable parallel processing with storm
streamparse and pystorm: simple reliable parallel processing with stormDaniel Blanchard
 
C++ Programming - 4th Study
C++ Programming - 4th StudyC++ Programming - 4th Study
C++ Programming - 4th StudyChris Ohk
 
Implementing of classical synchronization problem by using semaphores
Implementing of classical synchronization problem by using semaphoresImplementing of classical synchronization problem by using semaphores
Implementing of classical synchronization problem by using semaphoresGowtham Reddy
 
how to reuse code
how to reuse codehow to reuse code
how to reuse codejleed1
 
Advanced Python, Part 2
Advanced Python, Part 2Advanced Python, Part 2
Advanced Python, Part 2Zaar Hai
 
Asterisk: PVS-Studio Takes Up Telephony
Asterisk: PVS-Studio Takes Up TelephonyAsterisk: PVS-Studio Takes Up Telephony
Asterisk: PVS-Studio Takes Up TelephonyAndrey Karpov
 
Georgy Nosenko - An introduction to the use SMT solvers for software security
Georgy Nosenko - An introduction to the use SMT solvers for software securityGeorgy Nosenko - An introduction to the use SMT solvers for software security
Georgy Nosenko - An introduction to the use SMT solvers for software securityDefconRussia
 

Similaire à Un monde où 1 ms vaut 100 M€ - Devoxx France 2015 (20)

5 must have patterns for your microservice - techorama
5 must have patterns for your microservice - techorama5 must have patterns for your microservice - techorama
5 must have patterns for your microservice - techorama
 
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
 
Actor Concurrency
Actor ConcurrencyActor Concurrency
Actor Concurrency
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
 
LSFMM 2019 BPF Observability
LSFMM 2019 BPF ObservabilityLSFMM 2019 BPF Observability
LSFMM 2019 BPF Observability
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
 
#ifndef CRYPTO_HPP#define CRYPTO_HPP#include functional#.docx
#ifndef CRYPTO_HPP#define CRYPTO_HPP#include functional#.docx#ifndef CRYPTO_HPP#define CRYPTO_HPP#include functional#.docx
#ifndef CRYPTO_HPP#define CRYPTO_HPP#include functional#.docx
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++
 
Zn task - defcon russia 20
Zn task  - defcon russia 20Zn task  - defcon russia 20
Zn task - defcon russia 20
 
How to stop debugging asynchronous code and start living, Andrey Salomatin, B...
How to stop debugging asynchronous code and start living, Andrey Salomatin, B...How to stop debugging asynchronous code and start living, Andrey Salomatin, B...
How to stop debugging asynchronous code and start living, Andrey Salomatin, B...
 
streamparse and pystorm: simple reliable parallel processing with storm
streamparse and pystorm: simple reliable parallel processing with stormstreamparse and pystorm: simple reliable parallel processing with storm
streamparse and pystorm: simple reliable parallel processing with storm
 
C++ Programming - 4th Study
C++ Programming - 4th StudyC++ Programming - 4th Study
C++ Programming - 4th Study
 
Oop object oriented programing topics
Oop object oriented programing topicsOop object oriented programing topics
Oop object oriented programing topics
 
Implementing of classical synchronization problem by using semaphores
Implementing of classical synchronization problem by using semaphoresImplementing of classical synchronization problem by using semaphores
Implementing of classical synchronization problem by using semaphores
 
how to reuse code
how to reuse codehow to reuse code
how to reuse code
 
Advanced Python, Part 2
Advanced Python, Part 2Advanced Python, Part 2
Advanced Python, Part 2
 
Quiz 9
Quiz 9Quiz 9
Quiz 9
 
Asterisk: PVS-Studio Takes Up Telephony
Asterisk: PVS-Studio Takes Up TelephonyAsterisk: PVS-Studio Takes Up Telephony
Asterisk: PVS-Studio Takes Up Telephony
 
Ping to Pong
Ping to PongPing to Pong
Ping to Pong
 
Georgy Nosenko - An introduction to the use SMT solvers for software security
Georgy Nosenko - An introduction to the use SMT solvers for software securityGeorgy Nosenko - An introduction to the use SMT solvers for software security
Georgy Nosenko - An introduction to the use SMT solvers for software security
 

Dernier

Chizaram's Women Tech Makers Deck. .pptx
Chizaram's Women Tech Makers Deck.  .pptxChizaram's Women Tech Makers Deck.  .pptx
Chizaram's Women Tech Makers Deck. .pptxogubuikealex
 
Engaging Eid Ul Fitr Presentation for Kindergartners.pptx
Engaging Eid Ul Fitr Presentation for Kindergartners.pptxEngaging Eid Ul Fitr Presentation for Kindergartners.pptx
Engaging Eid Ul Fitr Presentation for Kindergartners.pptxAsifArshad8
 
RACHEL-ANN M. TENIBRO PRODUCT RESEARCH PRESENTATION
RACHEL-ANN M. TENIBRO PRODUCT RESEARCH PRESENTATIONRACHEL-ANN M. TENIBRO PRODUCT RESEARCH PRESENTATION
RACHEL-ANN M. TENIBRO PRODUCT RESEARCH PRESENTATIONRachelAnnTenibroAmaz
 
INDIAN GCP GUIDELINE. for Regulatory affair 1st sem CRR
INDIAN GCP GUIDELINE. for Regulatory  affair 1st sem CRRINDIAN GCP GUIDELINE. for Regulatory  affair 1st sem CRR
INDIAN GCP GUIDELINE. for Regulatory affair 1st sem CRRsarwankumar4524
 
Don't Miss Out: Strategies for Making the Most of the Ethena DigitalOpportunity
Don't Miss Out: Strategies for Making the Most of the Ethena DigitalOpportunityDon't Miss Out: Strategies for Making the Most of the Ethena DigitalOpportunity
Don't Miss Out: Strategies for Making the Most of the Ethena DigitalOpportunityApp Ethena
 
Application of GIS in Landslide Disaster Response.pptx
Application of GIS in Landslide Disaster Response.pptxApplication of GIS in Landslide Disaster Response.pptx
Application of GIS in Landslide Disaster Response.pptxRoquia Salam
 
General Elections Final Press Noteas per M
General Elections Final Press Noteas per MGeneral Elections Final Press Noteas per M
General Elections Final Press Noteas per MVidyaAdsule1
 
Testing and Development Challenges for Complex Cyber-Physical Systems: Insigh...
Testing and Development Challenges for Complex Cyber-Physical Systems: Insigh...Testing and Development Challenges for Complex Cyber-Physical Systems: Insigh...
Testing and Development Challenges for Complex Cyber-Physical Systems: Insigh...Sebastiano Panichella
 
proposal kumeneger edited.docx A kumeeger
proposal kumeneger edited.docx A kumeegerproposal kumeneger edited.docx A kumeeger
proposal kumeneger edited.docx A kumeegerkumenegertelayegrama
 
Testing with Fewer Resources: Toward Adaptive Approaches for Cost-effective ...
Testing with Fewer Resources:  Toward Adaptive Approaches for Cost-effective ...Testing with Fewer Resources:  Toward Adaptive Approaches for Cost-effective ...
Testing with Fewer Resources: Toward Adaptive Approaches for Cost-effective ...Sebastiano Panichella
 
GESCO SE Press and Analyst Conference on Financial Results 2024
GESCO SE Press and Analyst Conference on Financial Results 2024GESCO SE Press and Analyst Conference on Financial Results 2024
GESCO SE Press and Analyst Conference on Financial Results 2024GESCO SE
 
cse-csp batch4 review-1.1.pptx cyber security
cse-csp batch4 review-1.1.pptx cyber securitycse-csp batch4 review-1.1.pptx cyber security
cse-csp batch4 review-1.1.pptx cyber securitysandeepnani2260
 
Quality by design.. ppt for RA (1ST SEM
Quality by design.. ppt for  RA (1ST SEMQuality by design.. ppt for  RA (1ST SEM
Quality by design.. ppt for RA (1ST SEMCharmi13
 
05.02 MMC - Assignment 4 - Image Attribution Lovepreet.pptx
05.02 MMC - Assignment 4 - Image Attribution Lovepreet.pptx05.02 MMC - Assignment 4 - Image Attribution Lovepreet.pptx
05.02 MMC - Assignment 4 - Image Attribution Lovepreet.pptxerickamwana1
 
Internship Presentation | PPT | CSE | SE
Internship Presentation | PPT | CSE | SEInternship Presentation | PPT | CSE | SE
Internship Presentation | PPT | CSE | SESaleh Ibne Omar
 
A Guide to Choosing the Ideal Air Cooler
A Guide to Choosing the Ideal Air CoolerA Guide to Choosing the Ideal Air Cooler
A Guide to Choosing the Ideal Air Coolerenquirieskenstar
 
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...漢銘 謝
 

Dernier (17)

Chizaram's Women Tech Makers Deck. .pptx
Chizaram's Women Tech Makers Deck.  .pptxChizaram's Women Tech Makers Deck.  .pptx
Chizaram's Women Tech Makers Deck. .pptx
 
Engaging Eid Ul Fitr Presentation for Kindergartners.pptx
Engaging Eid Ul Fitr Presentation for Kindergartners.pptxEngaging Eid Ul Fitr Presentation for Kindergartners.pptx
Engaging Eid Ul Fitr Presentation for Kindergartners.pptx
 
RACHEL-ANN M. TENIBRO PRODUCT RESEARCH PRESENTATION
RACHEL-ANN M. TENIBRO PRODUCT RESEARCH PRESENTATIONRACHEL-ANN M. TENIBRO PRODUCT RESEARCH PRESENTATION
RACHEL-ANN M. TENIBRO PRODUCT RESEARCH PRESENTATION
 
INDIAN GCP GUIDELINE. for Regulatory affair 1st sem CRR
INDIAN GCP GUIDELINE. for Regulatory  affair 1st sem CRRINDIAN GCP GUIDELINE. for Regulatory  affair 1st sem CRR
INDIAN GCP GUIDELINE. for Regulatory affair 1st sem CRR
 
Don't Miss Out: Strategies for Making the Most of the Ethena DigitalOpportunity
Don't Miss Out: Strategies for Making the Most of the Ethena DigitalOpportunityDon't Miss Out: Strategies for Making the Most of the Ethena DigitalOpportunity
Don't Miss Out: Strategies for Making the Most of the Ethena DigitalOpportunity
 
Application of GIS in Landslide Disaster Response.pptx
Application of GIS in Landslide Disaster Response.pptxApplication of GIS in Landslide Disaster Response.pptx
Application of GIS in Landslide Disaster Response.pptx
 
General Elections Final Press Noteas per M
General Elections Final Press Noteas per MGeneral Elections Final Press Noteas per M
General Elections Final Press Noteas per M
 
Testing and Development Challenges for Complex Cyber-Physical Systems: Insigh...
Testing and Development Challenges for Complex Cyber-Physical Systems: Insigh...Testing and Development Challenges for Complex Cyber-Physical Systems: Insigh...
Testing and Development Challenges for Complex Cyber-Physical Systems: Insigh...
 
proposal kumeneger edited.docx A kumeeger
proposal kumeneger edited.docx A kumeegerproposal kumeneger edited.docx A kumeeger
proposal kumeneger edited.docx A kumeeger
 
Testing with Fewer Resources: Toward Adaptive Approaches for Cost-effective ...
Testing with Fewer Resources:  Toward Adaptive Approaches for Cost-effective ...Testing with Fewer Resources:  Toward Adaptive Approaches for Cost-effective ...
Testing with Fewer Resources: Toward Adaptive Approaches for Cost-effective ...
 
GESCO SE Press and Analyst Conference on Financial Results 2024
GESCO SE Press and Analyst Conference on Financial Results 2024GESCO SE Press and Analyst Conference on Financial Results 2024
GESCO SE Press and Analyst Conference on Financial Results 2024
 
cse-csp batch4 review-1.1.pptx cyber security
cse-csp batch4 review-1.1.pptx cyber securitycse-csp batch4 review-1.1.pptx cyber security
cse-csp batch4 review-1.1.pptx cyber security
 
Quality by design.. ppt for RA (1ST SEM
Quality by design.. ppt for  RA (1ST SEMQuality by design.. ppt for  RA (1ST SEM
Quality by design.. ppt for RA (1ST SEM
 
05.02 MMC - Assignment 4 - Image Attribution Lovepreet.pptx
05.02 MMC - Assignment 4 - Image Attribution Lovepreet.pptx05.02 MMC - Assignment 4 - Image Attribution Lovepreet.pptx
05.02 MMC - Assignment 4 - Image Attribution Lovepreet.pptx
 
Internship Presentation | PPT | CSE | SE
Internship Presentation | PPT | CSE | SEInternship Presentation | PPT | CSE | SE
Internship Presentation | PPT | CSE | SE
 
A Guide to Choosing the Ideal Air Cooler
A Guide to Choosing the Ideal Air CoolerA Guide to Choosing the Ideal Air Cooler
A Guide to Choosing the Ideal Air Cooler
 
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
 

Un monde où 1 ms vaut 100 M€ - Devoxx France 2015