Sunday, November 24, 2013
Situations when you must not forget to use the scala blocking statement when working with futures...
Futures imply the use of an execution context, a custom one or the default one. An execution context is a mechanism that manage threads for you, map operations to be executed on them, they come with internal default limits which are most of time proportional to the number of CPU you have. This default behavior is the right one when dealing with CPU consuming operations, but with IO this is not the case. If you need to call 100 remote calls (1 seconds required for each of them) on an other system and you have only 2 cpu, your total response time will be 50 seconds, for an almost 0% cpu usage on your host... That's why the blocking statement was introduced, it allows you to mark a code section as blocking, by blocking we mean time consuming and not cpu consuming. Thanks to this statement, the execution context will be able to grow as necessary, and you'll get very low latency. On my 6 cores CPU, 50 virtual remote calls (2 seconds for each call) require only 2056ms with the blocking statement, and it requires of course 18 seconds without it (18s * 6cpu = 108s * 1cpu).
Publié par david crosson à l'adresse 15:25
Create Futures outside the for-comprehension, in order for them to start immediately their operations. If you create your futures inside the for-comprehension, your execution will be sequential and not concurrent ! This is a mistake very easy to make, not so easy to detect because it won't fail, you just won't be able to use all your CPU as you should when the processing involves CPU, or for other cases check for example how many network connections are established simultaneously...
Publié par david crosson à l'adresse 14:56
Tuesday, October 1, 2013
Just published a scala project on github, to play with primes and ulam spiral. To generate a 500x500 ulam spiral use :
$ sbt "run 500"It will generate a PNG image file named "ulam-spiral-500.png"
$ sbt console" scala> sexyPrimeStream(4) res3: primes.Primes.PInteger = 17 scala> primeStream.take(15).toList res3: List[primes.Primes.PInteger] = List(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47) scala> sexyPrimeStream.take(5).toList res5: List[primes.Primes.PInteger] = List(5, 7, 11, 13, 17) scala> isolatedPrimeStream.take(10).toList res2: List[primes.Primes.PInteger] = List(23, 37, 47, 53, 67, 79, 83, 89, 97, 113)
Publié par david crosson à l'adresse 22:42
Saturday, September 28, 2013
Saturday, September 21, 2013
Saturday, September 14, 2013
Wednesday, July 31, 2013
Truly generic collection compaction functions, with the second one you can even provide a custom merge. By compaction I mean merging consecutive "identical" values into a single one.
Publié par david crosson à l'adresse 22:10