Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

functional programming efficiency vs imperative

I'm new to functional programming and I just ran into something and was wondering if there was a way around this.

Suppose I have

myArray = [
  { a : 1 }
  { a : 4 }
  { a : 5 }
  { a : 6 }
  { a : 7 }
  { a : 8 }
]

Let say I need to do statistical operations on this data set such as

const median = myArray[ Math.ceil( myArray.length / 2 ) ]['a'] // Math.ceil .. Side Effect?
const fiveOrMore = myArray.filter( value => value.a >= 5 )
const lessThanFive = myArray.filter( value => value.a < 5 )

Some arbitrary examples. The problem with this as of right now is that with increasing amount of statistical operations I need to do, the efficiency decreases.

With imperative style, I could do everything in ONE for loop. Is this the wrong approach to functional programming that I am taking or is it a trade off of functional programming paradigm itself?

like image 572
Aaron Avatar asked Jun 11 '18 18:06

Aaron


People also ask

Is functional programming more efficient?

Efficiency issuesFunctional programming languages are typically less efficient in their use of CPU and memory than imperative languages such as C and Pascal. This is related to the fact that some mutable data structures like arrays have a very straightforward implementation using present hardware.

Is functional better than imperative?

It involves writing programs in terms of functions and mathematical structures. It involves writing programs as series of instructions or statements that can actively modify memory. It is more expressive and safer as compared to imperative programming.

Is functional programming faster than imperative programming?

In contrast due to techniques like pattern matching a whole program like a parser written in an functional language may be much faster than one written in an imperative language because of the possibility of compilers to optimize the code.

How does functional programming differ from imperative programming?

Functional Programming is a programming paradigm that considers computation as the evaluation of mathematical functions and avoids changing state and mutable data. Imperative Programming is a programming paradigm that uses statements, that change a program's state.


2 Answers

This is of course less performant. And the performance hit is a trade off of the style you chose.

One may argue that it's not a big deal since the time complexity is O(n), the only difference is the constant. I'd say make sure you preformance-test your app. If it's slow -- it's time to optimize certain blocks of code.

Premature optimization is evil. There will be many cases where imperative code works faster or much faster of muchly much faster than the functional one, and depending on the case you may or may not be okay with that.

Also, there are various techniques to improve the performance. You don't necessarily want to change the style. Say, in some cases memoization can drastically boost the speed of the function, while keeping the code functional. Just think outside the box.

like image 135
Igor Soloydenko Avatar answered Sep 19 '22 12:09

Igor Soloydenko


With functional style you could have done it in one reduce too. Just have a function that checks the element is below and the accumulator would be a structure with two lists you are adding elements to.

If you are thinking about passing a list through a series of higher order functions then you can reduce overhead with Trancducers which basically works like individual map, filter but with no lists between the operations.

There are streams which employ lazy evaluation if perhaps you will not be using all the elements in your result.

And there are generators. Basically you can make several for loops and use ỳield to "return" a value and you can chain these since all generators can be iterated with for of. Also here you can halt whenever you have enough data.

So for all these there are pros and cons. Performance wise if you are going to calculate all the elements anyway using generators and streams will have a bit overhead. Transducers is perhaps the better option that gives composability with little list making, but the loop will of course be faster.

Testing is easier with functional implementations and you can test individual stages isolated. One very large loop that rules the whole app is often difficult to debug. This also goes when you have one reduce which just rewrites one loop in a functional style.

like image 21
Sylwester Avatar answered Sep 20 '22 12:09

Sylwester