@@ -280,6 +280,8 @@ See [promote_symtype](#promote_symtype)
280280struct Term{T} <: Symbolic{T}
281281 f:: Any
282282 arguments:: Any
283+ hash:: Ref{UInt} # hash cache
284+ Term {T} (f, xs) where {T} = new {T} (f, xs, Ref {UInt} (0 ))
283285end
284286
285287istree (t:: Term ) = true
@@ -294,7 +296,9 @@ arguments(x::Term) = getfield(x, :arguments)
294296hashvec (xs, z) = foldr (hash, xs, init= z)
295297
296298function Base. hash (t:: Term{T} , salt:: UInt ) where {T}
297- hashvec (arguments (t), hash (operation (t), hash (T, salt)))
299+ h = t. hash[]
300+ ! iszero (h) && return h
301+ t. hash[] = hashvec (arguments (t), hash (operation (t), hash (T, salt)))
298302end
299303
300304function term (f, args... ; type = nothing )
@@ -408,6 +412,7 @@ struct Add{X, T<:Number, D} <: Symbolic{X}
408412 coeff:: T
409413 dict:: D
410414 sorted_args_cache:: Ref{Any}
415+ hash:: Ref{UInt}
411416end
412417
413418function Add (T, coeff, dict)
@@ -418,7 +423,7 @@ function Add(T, coeff, dict)
418423 return _isone (v) ? k : Mul (T, makemul (v, k)... )
419424 end
420425
421- Add {T, typeof(coeff), typeof(dict)} (coeff, dict, Ref {Any} (nothing ))
426+ Add {T, typeof(coeff), typeof(dict)} (coeff, dict, Ref {Any} (nothing ), Ref {UInt} ( 0 ) )
422427end
423428
424429symtype (a:: Add{X} ) where {X} = X
@@ -434,7 +439,11 @@ function arguments(a::Add)
434439 a. sorted_args_cache[] = iszero (a. coeff) ? args : vcat (a. coeff, args)
435440end
436441
437- Base. hash (a:: Add , u:: UInt64 ) = hash (a. coeff, hash (a. dict, u))
442+ function Base. hash (a:: Add , u:: UInt64 )
443+ h = a. hash[]
444+ ! iszero (h) && return h
445+ a. hash[] = hash (0xaddaddaddaddadda , hash (a. coeff, hash (a. dict, u)))
446+ end
438447
439448Base. isequal (a:: Add , b:: Add ) = isequal (a. coeff, b. coeff) && isequal (a. dict, b. dict)
440449
@@ -529,6 +538,7 @@ struct Mul{X, T<:Number, D} <: Symbolic{X}
529538 coeff:: T
530539 dict:: D
531540 sorted_args_cache:: Ref{Any}
541+ hash:: Ref{UInt}
532542end
533543
534544function Mul (T, a,b)
@@ -541,7 +551,7 @@ function Mul(T, a,b)
541551 return Pow (first (pair), last (pair))
542552 end
543553 else
544- Mul {T, typeof(a), typeof(b)} (a,b, Ref {Any} (nothing ))
554+ Mul {T, typeof(a), typeof(b)} (a,b, Ref {Any} (nothing ), Ref {UInt} ( 0 ) )
545555 end
546556end
547557
@@ -557,7 +567,11 @@ function arguments(a::Mul)
557567 a. sorted_args_cache[] = isone (a. coeff) ? args : vcat (a. coeff, args)
558568end
559569
560- Base. hash (m:: Mul , u:: UInt64 ) = hash (m. coeff, hash (m. dict, u))
570+ function Base. hash (m:: Mul , u:: UInt64 )
571+ h = m. hash[]
572+ ! iszero (h) && return h
573+ m. hash[] = hash (0xaaaaaaaaaaaaaaa , hash (m. coeff, hash (m. dict, u)))
574+ end
561575
562576Base. isequal (a:: Mul , b:: Mul ) = isequal (a. coeff, b. coeff) && isequal (a. dict, b. dict)
563577
0 commit comments