Optimize canonicalization allocations

Improved performance of the canonicalization process by reusing internal data structures across multiple canonicalizer operations instead of allocating new ones each time. This reduces unnecessary memory allocations in a frequently-used code path.