MangelMaxime / Elmish.Canvas

https://mangelmaxime.github.io/Elmish.Canvas/
1 stars 2 forks source link

Prevent too many allocations #3

Open alfonsogarciacaro opened 6 years ago

alfonsogarciacaro commented 6 years ago

The API with the DrawOp union type is very nice, but it has one little problem: it's creating too many allocations. For example, Particle.draw in the Segments demo is running every frame and allocates the memory for the lists and one union type for each draw operation. For this sample is fine, but it may cause problems in more complex scenarios.

I can only think of two possible solutions at the moment:

MangelMaxime commented 6 years ago

The API with the DrawOp union type is very nice, but it has one little problem: it's creating too many allocations.

Indeed when doing some small profiling I saw that we are having a lot of GC call.

Force that the draw operations are calculated only once and then evaluated every frame: however, this may be difficult because of the way view functions work in Elmish.

I have no idea how to do this one :)

Offer an API that is just inline functions directly compiling to the draw instruction (wrapping everything in a function or a Lazy value to delay execution). This would probably be the most performant but the code would look quite imperative.

I have some ideas I need to explore here. And I think we will probably end up calling directly the native API in order to make the wrapper as thin as possible. Because if people use canvas they should have the best performance possible.

MangelMaxime commented 6 years ago

Another important note is that accessing directly the native API allow us to call functions like:

abstract createLinearGradient: x0: float * y0: float * x1: float * y1: float -> CanvasGradient
abstract createPattern: image: U3<HTMLImageElement, HTMLCanvasElement, HTMLVideoElement> * repetition: string -> CanvasPattern
abstract createRadialGradient: x0: float * y0: float * r0: float * x1: float * y1: float * r1: float -> CanvasGradient
abstract measureText: text: string -> TextMetrics

Which return a value. If we try to wrap them in the DU style we would need to create a branch in the view function in order to wait for the result or something like that. And it could be quickly messy I guess.

@alfonsogarciacaro Does Fable support the lazy keyword? Just asking because you pointed it out.

alfonsogarciacaro commented 6 years ago

Yes it does!