cache

package module
v0.0.0-...-76a7414 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2024 License: MIT Imports: 4 Imported by: 0

README

Generic Caching

The two hardest things in computer science: naming things, cache invalidation, and off by one errors

This package implements a caching for functions with a single input and single output. By using structs for function input and output we can cache any general function using struct hashing.

Benchmarks show it is only worth caching for function calls that are relatively expensive. Below function calls taking about 100 nanoseconds simply recomputing the function is less expensive than caching.

Beware! Caching a struct with a map field may not work as expected, as the map type does not have a guaranteed field order and is hence difficult to hash consistently. In general, do not cache on the map type and instead make a call into the map from the cached function, using the map key as the cache parameter.

Inspired and expanded from Skarlso/cache.

Example

See the tests under the tests directory for comprehensive examples.

package main

import (
    "github.com/hmcalister/GenericCaching"
) 

func main() {
    type params struct {
		IntegerParam int
		StringParam  string
		FloatParam   float64
	}

	type output struct {
		StringOutput string
		FloatOutput  float64
	}

	var f = func(p params) output {
		return output{
			StringOutput: p.StringParam,
			FloatOutput:  float64(p.IntegerParam) * p.FloatParam,
		}
	}

	c := cache.NewCache[params, output](f)

    // The result of this call is cached and will be returned 
    // on future calls with the same parameters without recomputation of f
	c.CallWithCache(params{
		IntegerParam: 1,
		StringParam:  "Caching!",
		FloatParam:   2.0,
	})
}

Other Discussions

  • Currently, the caching relies on a consistent hashing of the function inputs. This is difficult for structs in general, as discussed above for map types. It may be nice to add some consistent caching method for any struct, but this problem pushes up against the language specification.

  • The current caching algorithm requires encoding and hashing the parameter type. For generality, we encode the parameters into a string using encoding/gob and hash the resulting string using hash/fnv. It would be interesting to benchmark just how long this process takes in comparison to just recomputing the function. I imagine for some functions, such a f(int) -> int caching would be a detriment.

    • Update: Implementing some benchmarks have shown our assumption is correct. Only function calls longer than about one hundred nanoseconds are worth caching.
  • In future, it would be nice to add cache types for specifically numerical types only, such that the encoding could be numerical rather than a string, which may be faster.

  • In future, adding the option for cache durations would be interesting as well, such that cached values are also associated with a timestamp that allow for recomputation after some time.

  • In future, it may be nice to have some way to boot items from the cache to avoid memory exploding. However, this is a very difficult task as deciding on what to boot is non-trivial.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cache

type Cache[ParamType any, ReturnType any] struct {
	// contains filtered or unexported fields
}

func NewCache

func NewCache[ParamType any, ReturnType any](f CacheableFunction[ParamType, ReturnType]) *Cache[ParamType, ReturnType]

func (*Cache[ParamType, ReturnType]) CallWithCache

func (c *Cache[ParamType, ReturnType]) CallWithCache(params ParamType) ReturnType

type CacheableFunction

type CacheableFunction[ParamType any, ReturnType any] func(ParamType) ReturnType

Defines a function that returns a cacheable value.

A cachable function always has a single parameter and a single return. If your function requires multiple parameters or returns, wrap these in a struct.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL