1

I am developing a scientific program where there are several time consuming functions that are called from different other functions. I want to optimize these calls by avoid calling the same function with the same parameters more than once without breaking OO concepts such as encapsulation.

I tried to formulate a basic example of what I have. Class A has an object of class B from where I calculate intermediate results needed by class A functions. For example, in order for the functionA and functionB to calculate its results, each function needs to call the time_consuming_function on the object from B. Usually this functions are called from within a loop so the parameters (1 and 2) are the same among calls to functionA and functionB.

class ClassA {
  ClassB obj // member object

  return_type functionA(parameter1, parameter2) {
    value1 = obj.time_consuming_function(parameter1)
    value2 = obj.time_consuming_function(parameter2)

    return some_operation_with(value1, value2)
  }

  return_type functionB(parameter1, parameter2) {
    value1 = obj.time_consuming_function(parameter1)
    value2 = obj.time_consuming_function(parameter2)

    return some_operation_with(value1, value2)
  }
}

One solution would be create a structure to hold the calculated values among calls to ClassA functions, such as this example:

class ClassA {
  ClassB obj // member object

  return_type functionA(data) { // data is a structure to hold the values
    if (data.is_empty()) {
      data.value1 = obj.time_consuming_function(parameter1)
      data.value2 = obj.time_consuming_function(parameter2)
    }

    return some_operation_with(data.value1, data.value2)
  }

  return_type functionB(data) { // same data obj as before

    // this time data is not empty, so no calculation needed
    if (data.is_empty()) {
      data.value1 = obj.time_consuming_function(parameter1)
      data.value2 = obj.time_consuming_function(parameter2)
    }

    return some_operation_with(data.value1, data.value2)
  }
}

Another solution would be create a class Data to hold the data beforehand. In this case, having the parameters 1 and 2, I would update all properties that change with this parameter on class Data and when executing my functions from class A I would only need to use the values calculated previously. The class A would provide an interface to the Data class.

class Data {
  ClassA class_a_obj

  void update_values_that_depend_on_parameter1(class_a_obj, parameter1) {
    value1 = class_a_obj.time_consuming_function(parameter1)
  }

  void update_values_that_depend_on_parameter2(parameter2) {
    value2 = class_a_obj.time_consuming_function(parameter2)
  }
}

class ClassA {
  ClassB obj // member object

  return_type functionA(data) {
    return some_operation_with(data.value1, data.value2)
  }

  return_type functionB(data) { // same data obj as before

    return some_operation_with(data.value1, data.value2)
  }

  return_type time_consuming_function(parameter) {
    return obj.time_consuming_function(parameter)
  }
}

I wanted to know what you think of this problem and the proposed solutions. Are there other suitable and efficient solutions?

TL;DR:

I have a program that makes several calculations and each of this calculations calls functions to get intermediate values. These values are the same when called from functions that receive the same parameters, I am looking for a way to optimize these calls reusing those intermediate values.

What is the best way to reuse those values while still keeping a good Object Oriented design??

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • 1
    use memoization, you can use a general memoization to be safe, or if you need even more speed, you can develop a use case specific memoization – CoffeDeveloper Jun 23 '15 at 13:37

1 Answers1

3

Encapsulate the acces to these methods/ objects via a proxy that caches recent results and returns the cached result.

Mario The Spoon
  • 4,799
  • 1
  • 24
  • 36
  • 3
    @pedrolmota This is also called [memoization](https://en.wikipedia.org/wiki/Memoization). Have a look at e.g. this SO question: [Writing Universal memoization function in C++11](http://stackoverflow.com/questions/17805969/writing-universal-memoization-function-in-c11) – m.s. Jun 23 '15 at 11:00
  • Thank you guys for the answers, I didn't know about memoization and that is exactly what I needed! – Pedro Linhares Jun 23 '15 at 17:19