How to refactor code to make it functional style?

后端 未结 3 1254
星月不相逢
星月不相逢 2021-01-14 15:01

Playing with F#, I\'m trying to think of code in a more functional way. A large part of my work happens to be numerical in nature so I\'m thinking whether this re-education

3条回答
  •  借酒劲吻你
    2021-01-14 15:35

    These are actually two questions: one about improving the given code and one about functional numerical code in F#. Since the other answers already focus on the specific code, I'll focus on the more general question.

    Is it about performance?

    In my experience, the suitability of functional programming in numerics depends on the performance requirements. The more important execution time is, the more you may want to compromise on functional style.

    If performance is not an issue, functional code tends to work very well. It's succinct and safe, and it's closer to mathematical writing than imperative programming. Sure, some problems map very well to imperative programs, but overall, functional style makes a good default choice.

    If performance is somewhat an issue, you may want to compromise on immutability. The main cost of functional code in F# comes from the garbage collector, especially from objects with an intermediate lifetime. Making costly objects mutable and re-using them can make a huge difference in execution speed. If you want to write stuff like hydrodynamics, n-body simulations, or games, in a succinct and safe way, but aren't aiming for pedal-to-the-metal execution speed, a multiparadigm F# style can be a good way to go.

    If performance is everything, chances are, you want GPU execution anyway. Or maybe make good use of CPU vector units, multithreading, and so on. While there are attempts to use F# on the GPU, the language just isn't designed for speed at all cost. It's probably better to use a language that's closer to hardware in such situations.

    When the problem is a mixture of these, it's often possible to mix the solutions. For example, yesterday I needed to do a per-pixel computation on a set of images, and execution time was important. So I read the images in F# using a .NET library, then uploaded them to GPU along with a GLSL compute shader that transformed the pixels, then downloaded them back into "F# land". The point here is that the management operations aren't efficient; the code is still copying stuff around for no real reason. But it was just one operation that would've eaten all the performance, so it's reasonable to use a high-performance tool for that one operation, while all the rest happens neatly and safely in F#.

提交回复
热议问题