Allow side effect function

I defined a Comp module whose operations are quite expensive. In most cases, for a value of type Comp.t you can compute a value of type int , which can be used to speed up many operations. Therefore, I define the type of x as follows, which represents 2 cases: 1) an integer is calculated 2) otherwise

 type x = A of (Comp.t, int) | B of Comp.t 

The convert: x -> x function was written convert: x -> x to try to calculate an integer for a Comp.t , it is possible that this integer does not exist, this function is also expensive:

 let convert (v: x): x = match v with | A _ -> v | B c -> try to calculate the integer "i" from "c", return "A (c, i)" if the integer is found; otherwise, return "B c". 

Initially, the comparaison less than function can be written as follows:

 open Comp let lt (x0: x) (x1: x): bool = let x0, x1 = Comp.convert x0, Comp.convert x1 in match x0, x1 with | A (c0, i0), A (c1, i1) -> i0 < i1 (* which is very fast *) | A (c0, _), B c1 | B c0, A (c1, _) | B c0, B c1 -> Comp.lt c0 c1 (* which is quite slow *) ... let b0 = lt x0_o x1_o in let b1 = le x0_o x1_o in (* "le" call "convert" too *) let b2 = ge x0_o x1_o in (* "ge" call "convert" too *) ... 

Since convert is expensive, and there are many other functions than lt that can call it from time to time (e.g. le , ge ), I would like to make the conversion by affecting the value outside, For example, I want lt change the value of x0_o and x1_o , so that functions later (e.g. le , ge ) receive arguments that were probably already converted, which leads to faster computation for the entire block.

So, I think you need to use something like a mutable write, can anyone give me an example? Also, overall, is it a good idea to do this (by allowing side effects) to optimize the calculations?

+4
source share
1 answer

I think you want to make memoize ( https://en.wikipedia.org/wiki/Memoization ) the Comp.convert function (if it's clean):

This memoization code uses a hash table to store the results instead of recounting them (replacing the Comp.convert function is very simple to test the code):

 let convert x = x + 3 let convert_m' () = let tbl = Hashtbl.create 100 in (fun x -> if Hashtbl.mem tbl x then Hashtbl.find tbl x else begin let n = convert x in Hashtbl.add tbl xn; n end ) let convert_m = convert_m' () let b = convert_m 6 
+2
source

Source: https://habr.com/ru/post/1488154/


All Articles