Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Fabio Labella
@SystemFw
in Zio you have this bit of code
Mateusz Górski
@goral09
I wonder it this choice was an informed one (from scalaz-io RTS) :
val threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors().max(2))
Fabio Labella
@SystemFw
 // Fiber does not need to be interrupted, but might need to yield:
              if (opcount == maxopcount) {
                // Cooperatively yield to other fibers currently suspended.
                // FIXME: Replace with the new design.
                opcount = 0

                // Cannot capture `curIo` since it will be boxed into `ObjectRef`,
                // which destroys performance, so we create a temp val here.
                val tmpIo = curIo

                rts.submit(evaluate(tmpIo))

                curIo = null
Alexandru Nedelcu
@alexandru
Btw, in Monix we also have Scheduler, which is capable of executing Runnable units on the current thread.
This is then used in the implementation for stack safety and error reporting.
Fabio Labella
@SystemFw
yeah, I misspoke slightly
the biggest difference is that Fiber in scalaz is a concrete type that holds the runloop logic
whereas in monix and cats effect is mostly a view over the runloop
Alexandru Nedelcu
@alexandru
Ah, right, that makes sense.

I have some thoughts on improving the run loop, but I don't have time for experiments right now. I'm thinking of introducing the "visitor pattern" we now have in Iterant too ... when you end up with an ADT with a lot of states, the JVM can do that pattern matching better than you via plain old method dispatches, however for tight flatMap loops pattern matching is faster (saw it in testing) so I have to juggle those modes somewhat ... to switch between method dispatches (visitor) and pattern matching in hot loops.

Not sure how well that will work out without experiments. Plain old method dispatches would be cool for adding more specialized states (ContextSwitch is a recent example).

Fabio Labella
@SystemFw
the key idea is the stack of continuations in any case, that's just a really powerful interpretation technique (which I suspect is related to CEK/CESK machines)
I think that approach makes sense
finding out the exact threshold it's going to be tough though :)
Alexandru Nedelcu
@alexandru
Doing performance work is kind of stressful, since you try out things and most of the times you discover that you're wrong. Not fun.
Fabio Labella
@SystemFw
:+1:
Fabio Labella
@SystemFw

I wonder it this choice was an informed one (from scalaz-io RTS) :

val threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors().max(2))

@goral09 This is pretty std for CPU-bound work, when you have nonblocking implementations for most other things

if there are blocking concerns, then the evalOn we have, with a different ec, is the currently recommended choice
Mateusz Górski
@goral09
hmm, I must be missing sth. Isn't RTS for IO which is , io?
IO isn't necessarily CPU-bound
Fabio Labella
@SystemFw
yes, but ideally you will have non-blocking implementations for other things
e.g. http
for which the same (lack of) concern applies
the problem only appears when dealing with blocking constructs (which should be considered legacy imho)
that being said
it is a very real problem in practice
but in that case you still don't want to have a single EC for both things
this is what ContextShift and evalOn in cats-effect aim to solve
Mateusz Górski
@goral09
I understand
I thought that for IO the std is to have a cached thread pool with keepAlive
Fabio Labella
@SystemFw
IO or i/o
Mateusz Górski
@goral09
right, i/o
I see it now, thanks
Mateusz Górski
@goral09
it is kind of wishful thinking that everything submitted to the RTS is non-blocking
Fabio Labella
@SystemFw
at the end of the day, it's always up to the user to give a hint about blocking stuff
that's what blocking on global does
and what we achieve with ContextShift
Alexandru Nedelcu
@alexandru
Btw, I think Scala's global, which is a ForkJoinPool, works better as a default for CPU-bound stuff. Does some nifty work stealing stuff under the hood and the blocking integration is pretty cool too.
Talking about usage of Executors.newFixedThreadPool in Scalaz's RTS.
Mateusz Górski
@goral09
That would be my default choice as well.
Piotr Gawryś
@Avasil
How work stealing works for typicalIO/Task code? I don't see how it can be split. I have been wondering about it for a while and didn't find satisfactory answer yet
Fabio Labella
@SystemFw
yeah, I also prefer global, but that fixedThreadPool code doesn't particularly surprise me
the old Strategy in the scalaz world had that as a default
Alex Henning Johannessen
@ahjohannessen
@alexandru When do you expect to publish a Monix v3 that works with cats-effect 1.0.0?
Wogan
@wogan
Alex you can watch #710 for progress
Yann Simon
@yanns
Hello, newbie question: how do we transform an Observable[List[A]] into an Observable[A]?
Yohann B
@ybr
@yanns You can do myobs.flatMap(myList => Observable(myList.toSeq: _*)) or something like that
Yann Simon
@yanns
Thx, This is working (.flatMap(list ⇒ Observable.fromIterator(list.iterator))).
I was looking for a method that can do it directly like the mapConcat in akka streams.
Alexandru Nedelcu
@alexandru
Sorry guys, I cannot release a new versions with an API that I don't want to support in the final release. Cats-Effect 1.0.0 triggered some major changes in Task and the monix-eval sub-project, I have to finish that first. Working as hard as possible, given work and other obligations.
Alex Henning Johannessen
@ahjohannessen
@alexandru thanks for heads up