Skip to content

Commit

Permalink
Docs: Add comprehensive documentation for BasicSymbolic hash consing
Browse files Browse the repository at this point in the history
  • Loading branch information
bowenszhu committed Oct 25, 2024
1 parent 45cd224 commit 49a4e06
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,55 @@ end

wvd = WeakValueDict{UInt, BasicSymbolic}()

"""
$(TYPEDSIGNATURES)
This function implements hash consing for `BasicSymbolic` objects, ensuring that only one
unique instance of a given symbolic expression exists in memory.
Hash consing, also known as the flyweight pattern, is a powerful optimization technique
that can significantly reduce memory consumption and speed up symbolic computations by
eliminating duplicate objects.
# how it works
1. **Hashing:** The input `BasicSymbolic` object `s` is hashed using `hash2` to generate a
unique key.
2. **Lookup:** The `wvd` dictionary, a
[`WeakValueDict`](https://github.com/twavv/WeakValueDicts.jl), is checked to see if an
object with the same hash already exists.
3. **Return Existing Object:** If an object with the same hash is found and it `isequal`
to `s`, the existing object is returned, avoiding the creation of a duplicate.
4. **Handle Collisions and Return New Object:** If a hash collision occurs (two objects
with different symbolic expressions having the same hash), a warning is issued to alert
the user. The new object `s` is then returned and not stored in the `wvd` dictionary.
# Benefits of Hash Consing
- **Reduced Memory Consumption:** By eliminating duplicate symbolic objects, hash consing
significantly reduces memory usage.
- **Faster Equality Checks:** Checking for equality between symbolic expressions becomes a
simple pointer comparison, leading to speed-ups in algorithms that rely on equality
checks.
- **Implicit Common Subexpression Elimination (CSE):** Hash consing inherently performs
CSE. Since each subexpression is constructed only once, redundant computations are
avoided.
- **Accelerated Runtime Code Generation:** In scenarios involving runtime code generation,
hash consing reduces the number of unique symbolic expressions that need to be compiled.
# The `wvd` Dictionary (WeakValueDict)
The `wvd` dictionary uses weak references to its values. This means that if a symbolic
object loses all its strong references elsewhere in the code, it becomes eligible for
garbage collection, even if it's still present in the `wvd` dictionary.
# Example
```julia
expr1 = BasicSymbolic(...)
expr2 = BasicSymbolic(...) # the same mathematical expression
expr1 === expr2 # expr1 and expr2 refer to the same object in memory
```
"""
function BasicSymbolic(s::BasicSymbolic)::BasicSymbolic
h = hash2(s)
t = get!(wvd, h, s)
Expand Down

0 comments on commit 49a4e06

Please sign in to comment.