Skip to content

Caching/memoization of fields #113

Open

Description

@JulStraus

@hellemo was working on improving model construction. A major issue is related to the extraction of input and output resources, especially of links. As outlined in #110, we access the field every single time period in model construction. this is especially an issue with respect to the Link resources as they are calculated through the connected nodes. Three solutions were proposed:

  1. explicitly compute the resources once, store them in a dictionary, and access them from said dictionary (Compute node and link resources once when building flows and couplings #110),
  2. use the package Memoization.jl to precalculate the values when creating the model (Memoize link resources and node links with Memoization.jl #111), and
  3. create a similar routine as in Memoization.jl to reduce dependencies (Cache link resources and node links while a model is built #112).

I personally think it would be beneficial to discuss here which approach we want to utilize.

Compute node and link resources once when building flows and couplings (#110)

No pros or cons mentioned in the PR.

Memoize link resources and node links with Memoization.jl (#111)

Pros:

  • No change to the formulation
  • Benefits all extension packages

Cons:

  • An extra dependency
  • Global state

Cache link resources and node links while a model is built (#112)

Pros:

  • keeps the formulation and should benefit extension packages as well
  • no extra dependency

Cons:

  • a bit more code/complexity to maintain in this package

Activity

  1. JulStraus commented on Oct 19, 2026

    @JulStraus
    MemberAuthor

    Personally speaking, I think it is something which is quite relevant for each subtype of AbstractElement or comparable (i.e., TransmissionMode). In all situations, it boils down to provide a fast approach for the functions inputs and outputs although, due to the design of Direct, this is redirected to link_res.

    I personally think that we can work with the approach outlined in #110. I do not necessarily think that we need memoization or caching although it could potentially speed it up slightly later. The only places where we need these functions with a lot of calculations are variables_flow and constraints_couple. For both functions, new methods have to be defined when users create new subtypes of AbstractElement. What are your thoughts?

    Important

    The approach with link_res is internal within EnergyModelsBase as a fall back if no resources are specified. All Links in packages within this group have specific methods, e.g., (DhPipe or CapacityCostLink. This implies in my opinion that we should not focus specifically on this method, but instead on inputs and outputs.

  2. hellemo commented on Oct 21, 2026

    @hellemo
    Member

    For #110 it think the main would be:

    pro:

    • no global state

    con:

    • more invasive change of the constraints construction
    • does not benefit all users of the functions as the cache is explicit and on the outside

    I think I lean towards #112 as it keeps the native formulation and gets the performance benefit without taking on additional dependencies, but any of three should be ok.

  3. JulStraus commented on Oct 21, 2026

    @JulStraus
    MemberAuthor

    I agree with respect to leaning towards #112. However, #112 does not yet include caching/memoizing for inputs and outputs of nodes. The question is whether any caching/memoizing of these parameters do make sense? Is accessing dictionaries faster than the field access function? Have you tested it out?

  4. hellemo commented on Oct 21, 2026

    @hellemo
    Member

    I think the main win is from avoiding the repeated calculation of the intersection, so probably less potential for gains on plain inputs/outputs, but can have a look.

    EDIT: A quick test suggests dictionary lookups would not help for inputs/outputs, rather make it slower. It's indeed the intersection that is expensive.

  5. espenbodal commented on Oct 28, 2026

    @espenbodal
    Member

    #112 looks like a good solution to me. I don't have much more to add than what already has been mentioned.

  6. JulStraus commented on Oct 28, 2026

    @JulStraus
    MemberAuthor

    @hellemo It seems that we align with respect to #112. I will do a short review on it now That implies we can close #110 and #111.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions