diff --git a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
index 71739d43..cd36bdc0 100644
--- a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
+++ b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
@@ -50,6 +50,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
                 StackAlloc = stackAlloc;
                 Masks      = masks;
 
+                BitMapPool.PrepareBitMapPool();
+
                 Active   = BitMapPool.Allocate(intervalsCount);
                 Inactive = BitMapPool.Allocate(intervalsCount);
             }
@@ -73,7 +75,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
 
             public void Dispose()
             {
-                BitMapPool.Release();
+                BitMapPool.ResetBitMapPool();
             }
         }
 
@@ -84,7 +86,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
         {
             NumberLocals(cfg);
 
-            AllocationContext context = new AllocationContext(stackAlloc, regMasks, _intervals.Count);
+            using AllocationContext context = new AllocationContext(stackAlloc, regMasks, _intervals.Count);
 
             BuildIntervals(cfg, context);
 
@@ -127,14 +129,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
             InsertSplitCopies();
             InsertSplitCopiesAtEdges(cfg);
 
-            AllocationResult result = new AllocationResult(
-                context.IntUsedRegisters,
-                context.VecUsedRegisters,
-                context.StackAlloc.TotalSize);
-
-            context.Dispose();
-
-            return result;
+            return new AllocationResult(context.IntUsedRegisters, context.VecUsedRegisters, context.StackAlloc.TotalSize);
         }
 
         private void AllocateInterval(AllocationContext context, LiveInterval current, int cIndex)
diff --git a/ARMeilleure/CodeGen/X86/CodeGenContext.cs b/ARMeilleure/CodeGen/X86/CodeGenContext.cs
index da147cca..fa726f2f 100644
--- a/ARMeilleure/CodeGen/X86/CodeGenContext.cs
+++ b/ARMeilleure/CodeGen/X86/CodeGenContext.cs
@@ -2,6 +2,7 @@ using ARMeilleure.CodeGen.RegisterAllocators;
 using ARMeilleure.Common;
 using ARMeilleure.IntermediateRepresentation;
 using ARMeilleure.Translation.PTC;
+using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
@@ -301,15 +302,13 @@ namespace ARMeilleure.CodeGen.X86
             {
                 Assembler assembler = new Assembler(codeStream, _ptcInfo);
 
-                byte[] buffer;
-
                 for (int index = 0; index < _jumps.Count; index++)
                 {
                     Jump jump = _jumps[index];
 
-                    buffer = new byte[jump.JumpPosition - _stream.Position];
+                    Span<byte> buffer = new byte[jump.JumpPosition - _stream.Position];
 
-                    _stream.Read(buffer, 0, buffer.Length);
+                    _stream.Read(buffer);
                     _stream.Seek(_ptcDisabled ? ReservedBytesForJump : jump.InstSize, SeekOrigin.Current);
 
                     codeStream.Write(buffer);
@@ -324,13 +323,7 @@ namespace ARMeilleure.CodeGen.X86
                     }
                 }
 
-                buffer = new byte[_stream.Length - _stream.Position];
-
-                _stream.Read(buffer, 0, buffer.Length);
-
-                codeStream.Write(buffer);
-
-                _ptcInfo?.WriteCode(codeStream);
+                _stream.CopyTo(codeStream);
 
                 return codeStream.ToArray();
             }
diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs
index ca1f1ceb..3c14594d 100644
--- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs
+++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs
@@ -190,6 +190,11 @@ namespace ARMeilleure.CodeGen.X86
 
                 byte[] code = context.GetCode();
 
+                if (ptcInfo != null)
+                {
+                    ptcInfo.Code = code;
+                }
+
                 Logger.EndPass(PassName.CodeGeneration);
 
                 return new CompiledFunction(code, unwindInfo);
diff --git a/ARMeilleure/Common/BitMap.cs b/ARMeilleure/Common/BitMap.cs
index b1c9a673..f782ac8b 100644
--- a/ARMeilleure/Common/BitMap.cs
+++ b/ARMeilleure/Common/BitMap.cs
@@ -35,7 +35,7 @@ namespace ARMeilleure.Common
             }
         }
 
-        public void Reset(int initialCapacity)
+        public BitMap Reset(int initialCapacity)
         {
             int count = (initialCapacity + IntMask) / IntSize;
 
@@ -50,6 +50,8 @@ namespace ARMeilleure.Common
             {
                 _masks.Add(0);
             }
+
+            return this;
         }
 
         public bool Set(int bit)
diff --git a/ARMeilleure/Common/BitMapPool.cs b/ARMeilleure/Common/BitMapPool.cs
index aac32d55..d8d297fa 100644
--- a/ARMeilleure/Common/BitMapPool.cs
+++ b/ARMeilleure/Common/BitMapPool.cs
@@ -4,15 +4,29 @@
     {
         public static BitMap Allocate(int initialCapacity)
         {
-            BitMap result = ThreadStaticPool<BitMap>.Instance.Allocate();
-            result.Reset(initialCapacity);
-
-            return result;
+            return BitMap().Reset(initialCapacity);
         }
 
-        public static void Release()
+        #region "ThreadStaticPool"
+        public static void PrepareBitMapPool(int groupId = 0)
         {
-            ThreadStaticPool<BitMap>.Instance.Clear();
+            ThreadStaticPool<BitMap>.PreparePool(groupId, ChunkSizeLimit.Small);
         }
+
+        private static BitMap BitMap()
+        {
+            return ThreadStaticPool<BitMap>.Instance.Allocate();
+        }
+
+        public static void ResetBitMapPool(int groupId = 0)
+        {
+            ThreadStaticPool<BitMap>.ResetPool(groupId);
+        }
+
+        public static void DisposeBitMapPools()
+        {
+            ThreadStaticPool<BitMap>.DisposePools();
+        }
+        #endregion
     }
 }
diff --git a/ARMeilleure/Common/ThreadStaticPool.cs b/ARMeilleure/Common/ThreadStaticPool.cs
index e23bf1dc..bbe662f8 100644
--- a/ARMeilleure/Common/ThreadStaticPool.cs
+++ b/ARMeilleure/Common/ThreadStaticPool.cs
@@ -1,4 +1,5 @@
-using System;
+using ARMeilleure.Translation.PTC;
+using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 
@@ -6,9 +7,6 @@ namespace ARMeilleure.Common
 {
     class ThreadStaticPool<T> where T : class, new()
     {
-        private const int ChunkSizeLimit = 1000; // even
-        private const int PoolSizeIncrement = 200; // > 0
-
         [ThreadStatic]
         private static ThreadStaticPool<T> _instance;
 
@@ -18,21 +16,36 @@ namespace ARMeilleure.Common
             {
                 if (_instance == null)
                 {
-                    PreparePool(0); // So that we can still use a pool when blindly initializing one.
+                    PreparePool(); // So that we can still use a pool when blindly initializing one.
                 }
 
                 return _instance;
             }
         }
 
-        private static ConcurrentDictionary<int, Stack<ThreadStaticPool<T>>> _pools = new();
+        private static readonly ConcurrentDictionary<int, Stack<ThreadStaticPool<T>>> _pools = new();
 
         private static Stack<ThreadStaticPool<T>> GetPools(int groupId)
         {
             return _pools.GetOrAdd(groupId, (groupId) => new());
         }
 
-        public static void PreparePool(int groupId)
+        public static void PreparePool(
+            int groupId = 0,
+            ChunkSizeLimit chunkSizeLimit = ChunkSizeLimit.Large,
+            PoolSizeIncrement poolSizeIncrement = PoolSizeIncrement.Default)
+        {
+            if (Ptc.State == PtcState.Disabled)
+            {
+                PreparePoolDefault(groupId, (int)chunkSizeLimit, (int)poolSizeIncrement);
+            }
+            else
+            {
+                PreparePoolSlim((int)chunkSizeLimit, (int)poolSizeIncrement);
+            }
+        }
+
+        private static void PreparePoolDefault(int groupId, int chunkSizeLimit, int poolSizeIncrement)
         {
             // Prepare the pool for this thread, ideally using an existing one from the specified group.
 
@@ -41,27 +54,75 @@ namespace ARMeilleure.Common
                 var pools = GetPools(groupId);
                 lock (pools)
                 {
-                    _instance = (pools.Count != 0) ? pools.Pop() : new();
+                    _instance = (pools.Count != 0) ? pools.Pop() : new(chunkSizeLimit, poolSizeIncrement);
                 }
             }
         }
 
-        public static void ReturnPool(int groupId)
+        private static void PreparePoolSlim(int chunkSizeLimit, int poolSizeIncrement)
         {
-            // Reset, limit if necessary, and return the pool for this thread to the specified group.
+            // Prepare the pool for this thread.
 
-            var pools = GetPools(groupId);
-            lock (pools)
+            if (_instance == null)
             {
-                _instance.Clear();
-                _instance.ChunkSizeLimiter();
-                pools.Push(_instance);
-
-                _instance = null;
+                _instance = new(chunkSizeLimit, poolSizeIncrement);
             }
         }
 
-        public static void ResetPools()
+        public static void ResetPool(int groupId = 0)
+        {
+            if (Ptc.State == PtcState.Disabled)
+            {
+                ResetPoolDefault(groupId);
+            }
+            else
+            {
+                ResetPoolSlim();
+            }
+        }
+
+        private static void ResetPoolDefault(int groupId)
+        {
+            // Reset, limit if necessary, and return the pool for this thread to the specified group.
+
+            if (_instance != null)
+            {
+                var pools = GetPools(groupId);
+                lock (pools)
+                {
+                    _instance.Clear();
+                    _instance.ChunkSizeLimiter();
+                    pools.Push(_instance);
+
+                    _instance = null;
+                }
+            }
+        }
+
+        private static void ResetPoolSlim()
+        {
+            // Reset, limit if necessary, the pool for this thread.
+
+            if (_instance != null)
+            {
+                _instance.Clear();
+                _instance.ChunkSizeLimiter();
+            }
+        }
+
+        public static void DisposePools()
+        {
+            if (Ptc.State == PtcState.Disabled)
+            {
+                DisposePoolsDefault();
+            }
+            else
+            {
+                DisposePoolSlim();
+            }
+        }
+
+        private static void DisposePoolsDefault()
         {
             // Resets any static references to the pools used by threads for each group, allowing them to be garbage collected.
 
@@ -78,20 +139,37 @@ namespace ARMeilleure.Common
             _pools.Clear();
         }
 
+        private static void DisposePoolSlim()
+        {
+            // Dispose the pool for this thread.
+
+            if (_instance != null)
+            {
+                _instance.Dispose();
+
+                _instance = null;
+            }
+        }
+
         private List<T[]> _pool;
         private int _chunkIndex = -1;
         private int _poolIndex = -1;
+        private int _chunkSizeLimit;
+        private int _poolSizeIncrement;
 
-        private ThreadStaticPool()
+        private ThreadStaticPool(int chunkSizeLimit, int poolSizeIncrement)
         {
-            _pool = new(ChunkSizeLimit * 2);
+            _chunkSizeLimit = chunkSizeLimit;
+            _poolSizeIncrement = poolSizeIncrement;
+
+            _pool = new(chunkSizeLimit * 2);
 
             AddChunkIfNeeded();
         }
 
         public T Allocate()
         {
-            if (++_poolIndex >= PoolSizeIncrement)
+            if (++_poolIndex >= _poolSizeIncrement)
             {
                 AddChunkIfNeeded();
 
@@ -105,9 +183,9 @@ namespace ARMeilleure.Common
         {
             if (++_chunkIndex >= _pool.Count)
             {
-                T[] pool = new T[PoolSizeIncrement];
+                T[] pool = new T[_poolSizeIncrement];
 
-                for (int i = 0; i < PoolSizeIncrement; i++)
+                for (int i = 0; i < _poolSizeIncrement; i++)
                 {
                     pool[i] = new T();
                 }
@@ -124,18 +202,18 @@ namespace ARMeilleure.Common
 
         private void ChunkSizeLimiter()
         {
-            if (_pool.Count >= ChunkSizeLimit)
+            if (_pool.Count >= _chunkSizeLimit)
             {
-                int newChunkSize = ChunkSizeLimit / 2;
+                int newChunkSize = _chunkSizeLimit / 2;
 
                 _pool.RemoveRange(newChunkSize, _pool.Count - newChunkSize);
-                _pool.Capacity = ChunkSizeLimit * 2;
+                _pool.Capacity = _chunkSizeLimit * 2;
             }
         }
 
         private void Dispose()
         {
-            _pool.Clear();
+            _pool = null;
         }
     }
 }
diff --git a/ARMeilleure/Common/ThreadStaticPoolEnums.cs b/ARMeilleure/Common/ThreadStaticPoolEnums.cs
new file mode 100644
index 00000000..0d1d98d3
--- /dev/null
+++ b/ARMeilleure/Common/ThreadStaticPoolEnums.cs
@@ -0,0 +1,14 @@
+namespace ARMeilleure.Common
+{
+    public enum PoolSizeIncrement
+    {
+        Default = 200
+    }
+
+    public enum ChunkSizeLimit
+    {
+        Large = 200000 / PoolSizeIncrement.Default,
+        Medium = 100000 / PoolSizeIncrement.Default,
+        Small = 50000 / PoolSizeIncrement.Default
+    }
+}
\ No newline at end of file
diff --git a/ARMeilleure/IntermediateRepresentation/OperandHelper.cs b/ARMeilleure/IntermediateRepresentation/OperandHelper.cs
index f7381d86..26d66478 100644
--- a/ARMeilleure/IntermediateRepresentation/OperandHelper.cs
+++ b/ARMeilleure/IntermediateRepresentation/OperandHelper.cs
@@ -4,16 +4,6 @@ namespace ARMeilleure.IntermediateRepresentation
 {
     static class OperandHelper
     {
-        private static MemoryOperand MemoryOperand()
-        {
-            return ThreadStaticPool<MemoryOperand>.Instance.Allocate();
-        }
-
-        private static Operand Operand()
-        {
-            return ThreadStaticPool<Operand>.Instance.Allocate();
-        }
-
         public static Operand Const(OperandType type, long value)
         {
             return type == OperandType.I32 ? Operand().With((int)value) : Operand().With(value);
@@ -84,22 +74,34 @@ namespace ARMeilleure.IntermediateRepresentation
             return MemoryOperand().With(type, baseAddress, index, scale, displacement);
         }
 
-        public static void PrepareOperandPool(bool highCq)
+        #region "ThreadStaticPool"
+        public static void PrepareOperandPool(int groupId = 0)
         {
-            ThreadStaticPool<Operand>.PreparePool(highCq ? 1 : 0);
-            ThreadStaticPool<MemoryOperand>.PreparePool(highCq ? 1 : 0);
+            ThreadStaticPool<Operand>.PreparePool(groupId, ChunkSizeLimit.Large);
+            ThreadStaticPool<MemoryOperand>.PreparePool(groupId, ChunkSizeLimit.Small);
         }
 
-        public static void ReturnOperandPool(bool highCq)
+        private static Operand Operand()
         {
-            ThreadStaticPool<Operand>.ReturnPool(highCq ? 1 : 0);
-            ThreadStaticPool<MemoryOperand>.ReturnPool(highCq ? 1 : 0);
+            return ThreadStaticPool<Operand>.Instance.Allocate();
         }
 
-        public static void ResetOperandPools()
+        private static MemoryOperand MemoryOperand()
         {
-            ThreadStaticPool<Operand>.ResetPools();
-            ThreadStaticPool<MemoryOperand>.ResetPools();
+            return ThreadStaticPool<MemoryOperand>.Instance.Allocate();
         }
+
+        public static void ResetOperandPool(int groupId = 0)
+        {
+            ThreadStaticPool<MemoryOperand>.ResetPool(groupId);
+            ThreadStaticPool<Operand>.ResetPool(groupId);
+        }
+
+        public static void DisposeOperandPools()
+        {
+            ThreadStaticPool<Operand>.DisposePools();
+            ThreadStaticPool<MemoryOperand>.DisposePools();
+        }
+        #endregion
     }
 }
diff --git a/ARMeilleure/IntermediateRepresentation/OperationHelper.cs b/ARMeilleure/IntermediateRepresentation/OperationHelper.cs
index 538bdac4..0e560ee0 100644
--- a/ARMeilleure/IntermediateRepresentation/OperationHelper.cs
+++ b/ARMeilleure/IntermediateRepresentation/OperationHelper.cs
@@ -4,11 +4,6 @@ namespace ARMeilleure.IntermediateRepresentation
 {
     static class OperationHelper
     {
-        public static Operation Operation()
-        {
-            return ThreadStaticPool<Operation>.Instance.Allocate();
-        }
-
         public static Operation Operation(Instruction instruction, Operand destination)
         {
             return Operation().With(instruction, destination);
@@ -46,19 +41,26 @@ namespace ARMeilleure.IntermediateRepresentation
             return Operation().With(instruction, destinations, sources);
         }
 
-        public static void PrepareOperationPool(bool highCq)
+        #region "ThreadStaticPool"
+        public static void PrepareOperationPool(int groupId = 0)
         {
-            ThreadStaticPool<Operation>.PreparePool(highCq ? 1 : 0);
+            ThreadStaticPool<Operation>.PreparePool(groupId, ChunkSizeLimit.Medium);
         }
 
-        public static void ReturnOperationPool(bool highCq)
+        private static Operation Operation()
         {
-            ThreadStaticPool<Operation>.ReturnPool(highCq ? 1 : 0);
+            return ThreadStaticPool<Operation>.Instance.Allocate();
         }
 
-        public static void ResetOperationPools()
+        public static void ResetOperationPool(int groupId = 0)
         {
-            ThreadStaticPool<Operation>.ResetPools();
+            ThreadStaticPool<Operation>.ResetPool(groupId);
         }
+
+        public static void DisposeOperationPools()
+        {
+            ThreadStaticPool<Operation>.DisposePools();
+        }
+        #endregion
     }
 }
diff --git a/ARMeilleure/State/ExecutionMode.cs b/ARMeilleure/State/ExecutionMode.cs
index f43c5569..29154a25 100644
--- a/ARMeilleure/State/ExecutionMode.cs
+++ b/ARMeilleure/State/ExecutionMode.cs
@@ -1,6 +1,6 @@
 namespace ARMeilleure.State
 {
-    enum ExecutionMode
+    enum ExecutionMode : int
     {
         Aarch32Arm = 0,
         Aarch32Thumb = 1,
diff --git a/ARMeilleure/Translation/DirectCallStubs.cs b/ARMeilleure/Translation/DirectCallStubs.cs
index df7ca16e..85af6901 100644
--- a/ARMeilleure/Translation/DirectCallStubs.cs
+++ b/ARMeilleure/Translation/DirectCallStubs.cs
@@ -29,11 +29,17 @@ namespace ARMeilleure.Translation
             {
                 if (_initialized) return;
 
+                Translator.PreparePool();
+
                 _directCallStubPtr       = Marshal.GetFunctionPointerForDelegate<GuestFunction>(GenerateDirectCallStub(false));
                 _directTailCallStubPtr   = Marshal.GetFunctionPointerForDelegate<GuestFunction>(GenerateDirectCallStub(true));
                 _indirectCallStubPtr     = Marshal.GetFunctionPointerForDelegate<GuestFunction>(GenerateIndirectCallStub(false));
                 _indirectTailCallStubPtr = Marshal.GetFunctionPointerForDelegate<GuestFunction>(GenerateIndirectCallStub(true));
 
+                Translator.ResetPool();
+
+                Translator.DisposePools();
+
                 _initialized = true;
             }
         }
diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs
index f41f3464..5c608b3d 100644
--- a/ARMeilleure/Translation/EmitterContext.cs
+++ b/ARMeilleure/Translation/EmitterContext.cs
@@ -1,6 +1,7 @@
 using ARMeilleure.Diagnostics;
 using ARMeilleure.IntermediateRepresentation;
 using ARMeilleure.State;
+using ARMeilleure.Translation.PTC;
 using System;
 using System.Collections.Generic;
 using System.Reflection;
@@ -9,8 +10,6 @@ using static ARMeilleure.IntermediateRepresentation.OperandHelper;
 
 namespace ARMeilleure.Translation
 {
-    using PTC;
-
     class EmitterContext
     {
         private readonly Dictionary<Operand, BasicBlock> _irLabels;
diff --git a/ARMeilleure/Translation/JumpTableEntryAllocator.cs b/ARMeilleure/Translation/JumpTableEntryAllocator.cs
deleted file mode 100644
index 3b918628..00000000
--- a/ARMeilleure/Translation/JumpTableEntryAllocator.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using ARMeilleure.Common;
-using System.Collections.Generic;
-using System.Diagnostics;
-
-namespace ARMeilleure.Translation
-{
-    class JumpTableEntryAllocator
-    {
-        private readonly BitMap _bitmap;
-        private int _freeHint;
-
-        public JumpTableEntryAllocator()
-        {
-            _bitmap = new BitMap();
-        }
-
-        public bool EntryIsValid(int entryIndex)
-        {
-            lock (_bitmap)
-            {
-                return _bitmap.IsSet(entryIndex);
-            }
-        }
-
-        public void SetEntry(int entryIndex)
-        {
-            lock (_bitmap)
-            {
-                _bitmap.Set(entryIndex);
-            }
-        }
-
-        public int AllocateEntry()
-        {
-            lock (_bitmap)
-            {
-                int entryIndex;
-
-                if (!_bitmap.IsSet(_freeHint))
-                {
-                    entryIndex = _freeHint;
-                }
-                else
-                {
-                    entryIndex = _bitmap.FindFirstUnset();
-                }
-
-                _freeHint = entryIndex + 1;
-
-                bool wasSet = _bitmap.Set(entryIndex);
-                Debug.Assert(wasSet);
-
-                return entryIndex;
-            }
-        }
-
-        public void FreeEntry(int entryIndex)
-        {
-            lock (_bitmap)
-            {
-                _bitmap.Clear(entryIndex);
-
-                _freeHint = entryIndex;
-            }
-        }
-
-        public IEnumerable<int> GetEntries()
-        {
-            return _bitmap;
-        }
-    }
-}
diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs
index 6dd902bc..163e3efa 100644
--- a/ARMeilleure/Translation/PTC/Ptc.cs
+++ b/ARMeilleure/Translation/PTC/Ptc.cs
@@ -3,6 +3,7 @@ using ARMeilleure.CodeGen.Unwinding;
 using ARMeilleure.CodeGen.X86;
 using ARMeilleure.Memory;
 using ARMeilleure.Translation.Cache;
+using Ryujinx.Common;
 using Ryujinx.Common.Configuration;
 using Ryujinx.Common.Logging;
 using System;
@@ -12,17 +13,20 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.IO.Compression;
+using System.Runtime;
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
-using System.Security.Cryptography;
 using System.Threading;
 
+using static ARMeilleure.Translation.PTC.PtcFormatter;
+
 namespace ARMeilleure.Translation.PTC
 {
     public static class Ptc
     {
-        private const string HeaderMagic = "PTChd";
+        private const string HeaderMagicString = "PTChd\0\0\0";
 
-        private const int InternalVersion = 2010; //! To be incremented manually for each change to the ARMeilleure project.
+        private const uint InternalVersion = 1968; //! To be incremented manually for each change to the ARMeilleure project.
 
         private const string ActualDir = "0";
         private const string BackupDir = "1";
@@ -37,12 +41,14 @@ namespace ARMeilleure.Translation.PTC
         private const byte FillingByte = 0x00;
         private const CompressionLevel SaveCompressionLevel = CompressionLevel.Fastest;
 
-        private static readonly MemoryStream _infosStream;
-        private static readonly MemoryStream _codesStream;
-        private static readonly MemoryStream _relocsStream;
-        private static readonly MemoryStream _unwindInfosStream;
+        private static MemoryStream _infosStream;
+        private static MemoryStream _codesStream;
+        private static MemoryStream _relocsStream;
+        private static MemoryStream _unwindInfosStream;
 
-        private static readonly BinaryWriter _infosWriter;
+        private static BinaryWriter _infosWriter;
+
+        private static readonly ulong _headerMagic;
 
         private static readonly ManualResetEvent _waitEvent;
 
@@ -66,12 +72,9 @@ namespace ARMeilleure.Translation.PTC
 
         static Ptc()
         {
-            _infosStream = new MemoryStream();
-            _codesStream = new MemoryStream();
-            _relocsStream = new MemoryStream();
-            _unwindInfosStream = new MemoryStream();
+            InitializeMemoryStreams();
 
-            _infosWriter = new BinaryWriter(_infosStream, EncodingCache.UTF8NoBOM, true);
+            _headerMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(HeaderMagicString).AsSpan());
 
             _waitEvent = new ManualResetEvent(true);
 
@@ -95,13 +98,13 @@ namespace ARMeilleure.Translation.PTC
         public static void Initialize(string titleIdText, string displayVersion, bool enabled)
         {
             Wait();
-            ClearMemoryStreams();
-            PtcJumpTable.Clear();
 
             PtcProfiler.Wait();
             PtcProfiler.ClearEntries();
 
-            if (String.IsNullOrEmpty(titleIdText) || titleIdText == TitleIdTextDefault)
+            Logger.Info?.Print(LogClass.Ptc, $"Initializing Profiled Persistent Translation Cache (enabled: {enabled}).");
+
+            if (!enabled || string.IsNullOrEmpty(titleIdText) || titleIdText == TitleIdTextDefault)
             {
                 TitleIdText = TitleIdTextDefault;
                 DisplayVersion = DisplayVersionDefault;
@@ -114,55 +117,72 @@ namespace ARMeilleure.Translation.PTC
                 return;
             }
 
-            Logger.Info?.Print(LogClass.Ptc, $"Initializing Profiled Persistent Translation Cache (enabled: {enabled}).");
-
             TitleIdText = titleIdText;
-            DisplayVersion = !String.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
+            DisplayVersion = !string.IsNullOrEmpty(displayVersion) ? displayVersion : DisplayVersionDefault;
 
-            if (enabled)
+            string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir);
+            string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", BackupDir);
+
+            if (!Directory.Exists(workPathActual))
             {
-                string workPathActual = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", ActualDir);
-                string workPathBackup = Path.Combine(AppDataManager.GamesDirPath, TitleIdText, "cache", "cpu", BackupDir);
-
-                if (!Directory.Exists(workPathActual))
-                {
-                    Directory.CreateDirectory(workPathActual);
-                }
-
-                if (!Directory.Exists(workPathBackup))
-                {
-                    Directory.CreateDirectory(workPathBackup);
-                }
-
-                CachePathActual = Path.Combine(workPathActual, DisplayVersion);
-                CachePathBackup = Path.Combine(workPathBackup, DisplayVersion);
-
-                Enable();
-
-                PreLoad();
-                PtcProfiler.PreLoad();
+                Directory.CreateDirectory(workPathActual);
             }
-            else
+
+            if (!Directory.Exists(workPathBackup))
             {
-                CachePathActual = string.Empty;
-                CachePathBackup = string.Empty;
-
-                Disable();
+                Directory.CreateDirectory(workPathBackup);
             }
+
+            CachePathActual = Path.Combine(workPathActual, DisplayVersion);
+            CachePathBackup = Path.Combine(workPathBackup, DisplayVersion);
+
+            PreLoad();
+            PtcProfiler.PreLoad();
+
+            Enable();
         }
 
-        internal static void ClearMemoryStreams()
+        private static void InitializeMemoryStreams()
         {
-            _infosStream.SetLength(0L);
-            _codesStream.SetLength(0L);
-            _relocsStream.SetLength(0L);
-            _unwindInfosStream.SetLength(0L);
+            _infosStream = new MemoryStream();
+            _codesStream = new MemoryStream();
+            _relocsStream = new MemoryStream();
+            _unwindInfosStream = new MemoryStream();
+
+            _infosWriter = new BinaryWriter(_infosStream, EncodingCache.UTF8NoBOM, true);
+        }
+
+        private static void DisposeMemoryStreams()
+        {
+            _infosWriter.Dispose();
+
+            _infosStream.Dispose();
+            _codesStream.Dispose();
+            _relocsStream.Dispose();
+            _unwindInfosStream.Dispose();
+        }
+
+        private static bool AreMemoryStreamsEmpty()
+        {
+            return _infosStream.Length == 0L && _codesStream.Length == 0L && _relocsStream.Length == 0L && _unwindInfosStream.Length == 0L;
+        }
+
+        private static void ResetMemoryStreamsIfNeeded()
+        {
+            if (AreMemoryStreamsEmpty())
+            {
+                return;
+            }
+
+            DisposeMemoryStreams();
+
+            InitializeMemoryStreams();
         }
 
         private static void PreLoad()
         {
-            string fileNameActual = String.Concat(CachePathActual, ".cache");
-            string fileNameBackup = String.Concat(CachePathBackup, ".cache");
+            string fileNameActual = string.Concat(CachePathActual, ".cache");
+            string fileNameBackup = string.Concat(CachePathBackup, ".cache");
 
             FileInfo fileInfoActual = new FileInfo(fileNameActual);
             FileInfo fileInfoBackup = new FileInfo(fileNameBackup);
@@ -183,106 +203,144 @@ namespace ARMeilleure.Translation.PTC
             }
         }
 
-        private static bool Load(string fileName, bool isBackup)
+        private static unsafe bool Load(string fileName, bool isBackup)
         {
-            using (FileStream compressedStream = new FileStream(fileName, FileMode.Open))
-            using (DeflateStream deflateStream = new DeflateStream(compressedStream, CompressionMode.Decompress, true))
-            using (MemoryStream stream = new MemoryStream())
-            using (MD5 md5 = MD5.Create())
+            using (FileStream compressedStream = new(fileName, FileMode.Open))
+            using (DeflateStream deflateStream = new(compressedStream, CompressionMode.Decompress, true))
             {
-                int hashSize = md5.HashSize / 8;
+                Hash128 currentSizeHash = DeserializeStructure<Hash128>(compressedStream);
+
+                Span<byte> sizeBytes = new byte[sizeof(int)];
+                compressedStream.Read(sizeBytes);
+                Hash128 expectedSizeHash = XXHash128.ComputeHash(sizeBytes);
+
+                if (currentSizeHash != expectedSizeHash)
+                {
+                    InvalidateCompressedStream(compressedStream);
+
+                    return false;
+                }
+
+                int size = BinaryPrimitives.ReadInt32LittleEndian(sizeBytes);
+
+                IntPtr intPtr = IntPtr.Zero;
 
                 try
                 {
-                    deflateStream.CopyTo(stream);
+                    intPtr = Marshal.AllocHGlobal(size);
+
+                    using (UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), size, size, FileAccess.ReadWrite))
+                    {
+                        try
+                        {
+                            deflateStream.CopyTo(stream);
+                        }
+                        catch
+                        {
+                            InvalidateCompressedStream(compressedStream);
+
+                            return false;
+                        }
+
+                        int hashSize = Unsafe.SizeOf<Hash128>();
+
+                        stream.Seek(0L, SeekOrigin.Begin);
+                        Hash128 currentHash = DeserializeStructure<Hash128>(stream);
+
+                        ReadOnlySpan<byte> streamBytes = new(stream.PositionPointer, (int)(stream.Length - stream.Position));
+                        Hash128 expectedHash = XXHash128.ComputeHash(streamBytes);
+
+                        if (currentHash != expectedHash)
+                        {
+                            InvalidateCompressedStream(compressedStream);
+
+                            return false;
+                        }
+
+                        stream.Seek((long)hashSize, SeekOrigin.Begin);
+
+                        Header header = ReadHeader(stream);
+
+                        if (header.Magic != _headerMagic)
+                        {
+                            InvalidateCompressedStream(compressedStream);
+
+                            return false;
+                        }
+
+                        if (header.CacheFileVersion != InternalVersion)
+                        {
+                            InvalidateCompressedStream(compressedStream);
+
+                            return false;
+                        }
+
+                        if (header.Endianness != GetEndianness())
+                        {
+                            InvalidateCompressedStream(compressedStream);
+
+                            return false;
+                        }
+
+                        if (header.FeatureInfo != GetFeatureInfo())
+                        {
+                            InvalidateCompressedStream(compressedStream);
+
+                            return false;
+                        }
+
+                        if (header.OSPlatform != GetOSPlatform())
+                        {
+                            InvalidateCompressedStream(compressedStream);
+
+                            return false;
+                        }
+
+                        if (header.InfosLen % InfoEntry.Stride != 0)
+                        {
+                            InvalidateCompressedStream(compressedStream);
+
+                            return false;
+                        }
+
+                        ReadOnlySpan<byte> infosBuf = new(stream.PositionPointer, header.InfosLen);
+                        stream.Seek(header.InfosLen, SeekOrigin.Current);
+
+                        ReadOnlySpan<byte> codesBuf = new(stream.PositionPointer, header.CodesLen);
+                        stream.Seek(header.CodesLen, SeekOrigin.Current);
+
+                        ReadOnlySpan<byte> relocsBuf = new(stream.PositionPointer, header.RelocsLen);
+                        stream.Seek(header.RelocsLen, SeekOrigin.Current);
+
+                        ReadOnlySpan<byte> unwindInfosBuf = new(stream.PositionPointer, header.UnwindInfosLen);
+                        stream.Seek(header.UnwindInfosLen, SeekOrigin.Current);
+
+                        try
+                        {
+                            PtcJumpTable = PtcJumpTable.Deserialize(stream);
+                        }
+                        catch
+                        {
+                            PtcJumpTable = new PtcJumpTable();
+
+                            InvalidateCompressedStream(compressedStream);
+
+                            return false;
+                        }
+
+                        _infosStream.Write(infosBuf);
+                        _codesStream.Write(codesBuf);
+                        _relocsStream.Write(relocsBuf);
+                        _unwindInfosStream.Write(unwindInfosBuf);
+                    }
                 }
-                catch
+                finally
                 {
-                    InvalidateCompressedStream(compressedStream);
-
-                    return false;
+                    if (intPtr != IntPtr.Zero)
+                    {
+                        Marshal.FreeHGlobal(intPtr);
+                    }
                 }
-
-                stream.Seek(0L, SeekOrigin.Begin);
-
-                byte[] currentHash = new byte[hashSize];
-                stream.Read(currentHash, 0, hashSize);
-
-                byte[] expectedHash = md5.ComputeHash(stream);
-
-                if (!CompareHash(currentHash, expectedHash))
-                {
-                    InvalidateCompressedStream(compressedStream);
-
-                    return false;
-                }
-
-                stream.Seek((long)hashSize, SeekOrigin.Begin);
-
-                Header header = ReadHeader(stream);
-
-                if (header.Magic != HeaderMagic)
-                {
-                    InvalidateCompressedStream(compressedStream);
-
-                    return false;
-                }
-
-                if (header.CacheFileVersion != InternalVersion)
-                {
-                    InvalidateCompressedStream(compressedStream);
-
-                    return false;
-                }
-
-                if (header.FeatureInfo != GetFeatureInfo())
-                {
-                    InvalidateCompressedStream(compressedStream);
-
-                    return false;
-                }
-
-                if (header.OSPlatform != GetOSPlatform())
-                {
-                    InvalidateCompressedStream(compressedStream);
-
-                    return false;
-                }
-
-                if (header.InfosLen % InfoEntry.Stride != 0)
-                {
-                    InvalidateCompressedStream(compressedStream);
-
-                    return false;
-                }
-
-                byte[] infosBuf = new byte[header.InfosLen];
-                byte[] codesBuf = new byte[header.CodesLen];
-                byte[] relocsBuf = new byte[header.RelocsLen];
-                byte[] unwindInfosBuf = new byte[header.UnwindInfosLen];
-
-                stream.Read(infosBuf, 0, header.InfosLen);
-                stream.Read(codesBuf, 0, header.CodesLen);
-                stream.Read(relocsBuf, 0, header.RelocsLen);
-                stream.Read(unwindInfosBuf, 0, header.UnwindInfosLen);
-
-                try
-                {
-                    PtcJumpTable = PtcJumpTable.Deserialize(stream);
-                }
-                catch
-                {
-                    PtcJumpTable = new PtcJumpTable();
-
-                    InvalidateCompressedStream(compressedStream);
-
-                    return false;
-                }
-
-                _infosStream.Write(infosBuf, 0, header.InfosLen);
-                _codesStream.Write(codesBuf, 0, header.CodesLen);
-                _relocsStream.Write(relocsBuf, 0, header.RelocsLen);
-                _unwindInfosStream.Write(unwindInfosBuf, 0, header.UnwindInfosLen);
             }
 
             long fileSize = new FileInfo(fileName).Length;
@@ -292,20 +350,16 @@ namespace ARMeilleure.Translation.PTC
             return true;
         }
 
-        private static bool CompareHash(ReadOnlySpan<byte> currentHash, ReadOnlySpan<byte> expectedHash)
+        private static Header ReadHeader(Stream stream)
         {
-            return currentHash.SequenceEqual(expectedHash);
-        }
-
-        private static Header ReadHeader(MemoryStream stream)
-        {
-            using (BinaryReader headerReader = new BinaryReader(stream, EncodingCache.UTF8NoBOM, true))
+            using (BinaryReader headerReader = new(stream, EncodingCache.UTF8NoBOM, true))
             {
                 Header header = new Header();
 
-                header.Magic = headerReader.ReadString();
+                header.Magic = headerReader.ReadUInt64();
 
                 header.CacheFileVersion = headerReader.ReadUInt32();
+                header.Endianness = headerReader.ReadBoolean();
                 header.FeatureInfo = headerReader.ReadUInt64();
                 header.OSPlatform = headerReader.ReadUInt32();
 
@@ -323,87 +377,133 @@ namespace ARMeilleure.Translation.PTC
             compressedStream.SetLength(0L);
         }
 
-        private static void PreSave(object state)
+        private static void PreSave()
         {
             _waitEvent.Reset();
 
-            string fileNameActual = String.Concat(CachePathActual, ".cache");
-            string fileNameBackup = String.Concat(CachePathBackup, ".cache");
-
-            FileInfo fileInfoActual = new FileInfo(fileNameActual);
-
-            if (fileInfoActual.Exists && fileInfoActual.Length != 0L)
+            try
             {
-                File.Copy(fileNameActual, fileNameBackup, true);
-            }
+                string fileNameActual = string.Concat(CachePathActual, ".cache");
+                string fileNameBackup = string.Concat(CachePathBackup, ".cache");
 
-            Save(fileNameActual);
+                FileInfo fileInfoActual = new FileInfo(fileNameActual);
+
+                if (fileInfoActual.Exists && fileInfoActual.Length != 0L)
+                {
+                    File.Copy(fileNameActual, fileNameBackup, true);
+                }
+
+                Save(fileNameActual);
+            }
+            finally
+            {
+                ResetMemoryStreamsIfNeeded();
+                PtcJumpTable.ClearIfNeeded();
+
+                GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
+            }
 
             _waitEvent.Set();
         }
 
-        private static void Save(string fileName)
+        private static unsafe void Save(string fileName)
         {
             int translatedFuncsCount;
 
-            using (MemoryStream stream = new MemoryStream())
-            using (MD5 md5 = MD5.Create())
+            int hashSize = Unsafe.SizeOf<Hash128>();
+
+            int size = hashSize + Header.Size + GetMemoryStreamsLength() + PtcJumpTable.GetSerializeSize(PtcJumpTable);
+
+            Span<byte> sizeBytes = new byte[sizeof(int)];
+            BinaryPrimitives.WriteInt32LittleEndian(sizeBytes, size);
+            Hash128 sizeHash = XXHash128.ComputeHash(sizeBytes);
+
+            Span<byte> sizeHashBytes = new byte[hashSize];
+            MemoryMarshal.Write<Hash128>(sizeHashBytes, ref sizeHash);
+
+            IntPtr intPtr = IntPtr.Zero;
+
+            try
             {
-                int hashSize = md5.HashSize / 8;
+                intPtr = Marshal.AllocHGlobal(size);
 
-                stream.Seek((long)hashSize, SeekOrigin.Begin);
-
-                WriteHeader(stream);
-
-                _infosStream.WriteTo(stream);
-                _codesStream.WriteTo(stream);
-                _relocsStream.WriteTo(stream);
-                _unwindInfosStream.WriteTo(stream);
-
-                PtcJumpTable.Serialize(stream, PtcJumpTable);
-
-                translatedFuncsCount = GetInfosEntriesCount();
-
-                ClearMemoryStreams();
-                PtcJumpTable.Clear();
-
-                stream.Seek((long)hashSize, SeekOrigin.Begin);
-                byte[] hash = md5.ComputeHash(stream);
-
-                stream.Seek(0L, SeekOrigin.Begin);
-                stream.Write(hash, 0, hashSize);
-
-                using (FileStream compressedStream = new FileStream(fileName, FileMode.OpenOrCreate))
-                using (DeflateStream deflateStream = new DeflateStream(compressedStream, SaveCompressionLevel, true))
+                using (UnmanagedMemoryStream stream = new((byte*)intPtr.ToPointer(), size, size, FileAccess.ReadWrite))
                 {
-                    try
-                    {
-                        stream.WriteTo(deflateStream);
-                    }
-                    catch
-                    {
-                        compressedStream.Position = 0L;
-                    }
+                    stream.Seek((long)hashSize, SeekOrigin.Begin);
 
-                    if (compressedStream.Position < compressedStream.Length)
+                    WriteHeader(stream);
+
+                    _infosStream.WriteTo(stream);
+                    _codesStream.WriteTo(stream);
+                    _relocsStream.WriteTo(stream);
+                    _unwindInfosStream.WriteTo(stream);
+
+                    PtcJumpTable.Serialize(stream, PtcJumpTable);
+
+                    stream.Seek((long)hashSize, SeekOrigin.Begin);
+                    ReadOnlySpan<byte> streamBytes = new(stream.PositionPointer, (int)(stream.Length - stream.Position));
+                    Hash128 hash = XXHash128.ComputeHash(streamBytes);
+
+                    stream.Seek(0L, SeekOrigin.Begin);
+                    SerializeStructure(stream, hash);
+
+                    translatedFuncsCount = GetInfosEntriesCount();
+
+                    ResetMemoryStreamsIfNeeded();
+                    PtcJumpTable.ClearIfNeeded();
+
+                    using (FileStream compressedStream = new(fileName, FileMode.OpenOrCreate))
+                    using (DeflateStream deflateStream = new(compressedStream, SaveCompressionLevel, true))
                     {
-                        compressedStream.SetLength(compressedStream.Position);
+                        try
+                        {
+                            compressedStream.Write(sizeHashBytes);
+                            compressedStream.Write(sizeBytes);
+
+                            stream.Seek(0L, SeekOrigin.Begin);
+                            stream.CopyTo(deflateStream);
+                        }
+                        catch
+                        {
+                            compressedStream.Position = 0L;
+                        }
+
+                        if (compressedStream.Position < compressedStream.Length)
+                        {
+                            compressedStream.SetLength(compressedStream.Position);
+                        }
                     }
                 }
             }
+            finally
+            {
+                if (intPtr != IntPtr.Zero)
+                {
+                    Marshal.FreeHGlobal(intPtr);
+                }
+            }
 
             long fileSize = new FileInfo(fileName).Length;
 
-            Logger.Info?.Print(LogClass.Ptc, $"Saved Translation Cache (size: {fileSize} bytes, translated functions: {translatedFuncsCount}).");
+            if (fileSize != 0L)
+            {
+                Logger.Info?.Print(LogClass.Ptc, $"Saved Translation Cache (size: {fileSize} bytes, translated functions: {translatedFuncsCount}).");
+            }
         }
 
-        private static void WriteHeader(MemoryStream stream)
+        private static int GetMemoryStreamsLength()
         {
-            using (BinaryWriter headerWriter = new BinaryWriter(stream, EncodingCache.UTF8NoBOM, true))
+            return (int)_infosStream.Length + (int)_codesStream.Length + (int)_relocsStream.Length + (int)_unwindInfosStream.Length;
+        }
+
+        private static void WriteHeader(Stream stream)
+        {
+            using (BinaryWriter headerWriter = new(stream, EncodingCache.UTF8NoBOM, true))
             {
-                headerWriter.Write((string)HeaderMagic); // Header.Magic
+                headerWriter.Write((ulong)_headerMagic); // Header.Magic
 
                 headerWriter.Write((uint)InternalVersion); // Header.CacheFileVersion
+                headerWriter.Write((bool)GetEndianness()); // Header.Endianness
                 headerWriter.Write((ulong)GetFeatureInfo()); // Header.FeatureInfo
                 headerWriter.Write((uint)GetOSPlatform()); // Header.OSPlatform
 
@@ -416,10 +516,7 @@ namespace ARMeilleure.Translation.PTC
 
         internal static void LoadTranslations(ConcurrentDictionary<ulong, TranslatedFunction> funcs, IMemoryManager memory, JumpTable jumpTable)
         {
-            if ((int)_infosStream.Length == 0 ||
-                (int)_codesStream.Length == 0 ||
-                (int)_relocsStream.Length == 0 ||
-                (int)_unwindInfosStream.Length == 0)
+            if (AreMemoryStreamsEmpty())
             {
                 return;
             }
@@ -431,10 +528,10 @@ namespace ARMeilleure.Translation.PTC
             _relocsStream.Seek(0L, SeekOrigin.Begin);
             _unwindInfosStream.Seek(0L, SeekOrigin.Begin);
 
-            using (BinaryReader infosReader = new BinaryReader(_infosStream, EncodingCache.UTF8NoBOM, true))
-            using (BinaryReader codesReader = new BinaryReader(_codesStream, EncodingCache.UTF8NoBOM, true))
-            using (BinaryReader relocsReader = new BinaryReader(_relocsStream, EncodingCache.UTF8NoBOM, true))
-            using (BinaryReader unwindInfosReader = new BinaryReader(_unwindInfosStream, EncodingCache.UTF8NoBOM, true))
+            using (BinaryReader infosReader = new(_infosStream, EncodingCache.UTF8NoBOM, true))
+            using (BinaryReader codesReader = new(_codesStream, EncodingCache.UTF8NoBOM, true))
+            using (BinaryReader relocsReader = new(_relocsStream, EncodingCache.UTF8NoBOM, true))
+            using (BinaryReader unwindInfosReader = new(_unwindInfosStream, EncodingCache.UTF8NoBOM, true))
             {
                 for (int i = 0; i < GetInfosEntriesCount(); i++)
                 {
@@ -446,9 +543,9 @@ namespace ARMeilleure.Translation.PTC
                         SkipReloc(infoEntry.RelocEntriesCount);
                         SkipUnwindInfo(unwindInfosReader);
                     }
-                    else if (infoEntry.HighCq || !PtcProfiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out var value) || !value.highCq)
+                    else if (infoEntry.HighCq || !PtcProfiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out var value) || !value.HighCq)
                     {
-                        byte[] code = ReadCode(codesReader, infoEntry.CodeLen);
+                        Span<byte> code = ReadCode(codesReader, infoEntry.CodeLen);
 
                         if (infoEntry.RelocEntriesCount != 0)
                         {
@@ -529,11 +626,11 @@ namespace ARMeilleure.Translation.PTC
             _unwindInfosStream.Seek(pushEntriesLength * UnwindPushEntry.Stride + UnwindInfo.Stride, SeekOrigin.Current);
         }
 
-        private static byte[] ReadCode(BinaryReader codesReader, int codeLen)
+        private static Span<byte> ReadCode(BinaryReader codesReader, int codeLen)
         {
-            byte[] codeBuf = new byte[codeLen];
+            Span<byte> codeBuf = new byte[codeLen];
 
-            codesReader.Read(codeBuf, 0, codeLen);
+            codesReader.Read(codeBuf);
 
             return codeBuf;
         }
@@ -605,9 +702,9 @@ namespace ARMeilleure.Translation.PTC
             return new UnwindInfo(pushEntries, prologueSize);
         }
 
-        private static TranslatedFunction FastTranslate(byte[] code, ulong guestSize, UnwindInfo unwindInfo, bool highCq)
+        private static TranslatedFunction FastTranslate(ReadOnlySpan<byte> code, ulong guestSize, UnwindInfo unwindInfo, bool highCq)
         {
-            CompiledFunction cFunc = new CompiledFunction(code, unwindInfo);
+            CompiledFunction cFunc = new CompiledFunction(code.ToArray(), unwindInfo);
 
             IntPtr codePtr = JitCache.Map(cFunc);
 
@@ -663,6 +760,11 @@ namespace ARMeilleure.Translation.PTC
 
             if (profiledFuncsToTranslate.Count == 0)
             {
+                ResetMemoryStreamsIfNeeded();
+                PtcJumpTable.ClearIfNeeded();
+
+                GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
+
                 return;
             }
 
@@ -696,6 +798,8 @@ namespace ARMeilleure.Translation.PTC
                         break;
                     }
                 }
+
+                Translator.DisposePools();
             }
 
             int maxDegreeOfParallelism = (Environment.ProcessorCount * 3) / 4;
@@ -715,8 +819,6 @@ namespace ARMeilleure.Translation.PTC
 
             threads.Clear();
 
-            Translator.ResetPools();
-
             _loggerEvent.Set();
 
             PtcJumpTable.Initialize(jumpTable);
@@ -724,7 +826,9 @@ namespace ARMeilleure.Translation.PTC
             PtcJumpTable.ReadJumpTable(jumpTable);
             PtcJumpTable.ReadDynamicTable(jumpTable);
 
-            ThreadPool.QueueUserWorkItem(PreSave);
+            Thread preSaveThread = new Thread(PreSave);
+            preSaveThread.IsBackground = true;
+            preSaveThread.Start();
         }
 
         private static void TranslationLogger(object state)
@@ -751,11 +855,11 @@ namespace ARMeilleure.Translation.PTC
                 _infosWriter.Write((ulong)guestSize); // InfoEntry.GuestSize
                 _infosWriter.Write((bool)highCq); // InfoEntry.HighCq
                 _infosWriter.Write((bool)false); // InfoEntry.Stubbed
-                _infosWriter.Write((int)ptcInfo.CodeStream.Length); // InfoEntry.CodeLen
+                _infosWriter.Write((int)ptcInfo.Code.Length); // InfoEntry.CodeLen
                 _infosWriter.Write((int)ptcInfo.RelocEntriesCount); // InfoEntry.RelocEntriesCount
 
                 // WriteCode.
-                ptcInfo.CodeStream.WriteTo(_codesStream);
+                _codesStream.Write(ptcInfo.Code.AsSpan());
 
                 // WriteReloc.
                 ptcInfo.RelocStream.WriteTo(_relocsStream);
@@ -765,6 +869,11 @@ namespace ARMeilleure.Translation.PTC
             }
         }
 
+        private static bool GetEndianness()
+        {
+            return BitConverter.IsLittleEndian;
+        }
+
         private static ulong GetFeatureInfo()
         {
             return (ulong)HardwareCapabilities.FeatureInfoEdx << 32 | (uint)HardwareCapabilities.FeatureInfoEcx;
@@ -784,9 +893,12 @@ namespace ARMeilleure.Translation.PTC
 
         private struct Header
         {
-            public string Magic;
+            public const int Size = 41; // Bytes.
+
+            public ulong Magic;
 
             public uint CacheFileVersion;
+            public bool Endianness;
             public ulong FeatureInfo;
             public uint OSPlatform;
 
@@ -849,12 +961,9 @@ namespace ARMeilleure.Translation.PTC
                 Wait();
                 _waitEvent.Dispose();
 
-                _infosWriter.Dispose();
+                _loggerEvent.Dispose();
 
-                _infosStream.Dispose();
-                _codesStream.Dispose();
-                _relocsStream.Dispose();
-                _unwindInfosStream.Dispose();
+                DisposeMemoryStreams();
             }
         }
     }
diff --git a/ARMeilleure/Translation/PTC/PtcFormatter.cs b/ARMeilleure/Translation/PTC/PtcFormatter.cs
new file mode 100644
index 00000000..7346b484
--- /dev/null
+++ b/ARMeilleure/Translation/PTC/PtcFormatter.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace ARMeilleure.Translation.PTC
+{
+    public class PtcFormatter
+    {
+        #region "Deserialize"
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static Dictionary<TKey, TValue> DeserializeDictionary<TKey, TValue>(Stream stream, Func<Stream, TValue> valueFunc) where TKey : unmanaged
+        {
+            Dictionary<TKey, TValue> dictionary = new();
+
+            int count = DeserializeStructure<int>(stream);
+
+            for (int i = 0; i < count; i++)
+            {
+                TKey key = DeserializeStructure<TKey>(stream);
+                TValue value = valueFunc(stream);
+
+                dictionary.Add(key, value);
+            }
+
+            return dictionary;
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static List<T> DeserializeList<T>(Stream stream) where T : unmanaged
+        {
+            List<T> list = new();
+
+            int count = DeserializeStructure<int>(stream);
+
+            for (int i = 0; i < count; i++)
+            {
+                T item = DeserializeStructure<T>(stream);
+
+                list.Add(item);
+            }
+
+            return list;
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static T DeserializeStructure<T>(Stream stream) where T : unmanaged
+        {
+            T structure = default(T);
+
+            Span<T> spanT = MemoryMarshal.CreateSpan(ref structure, 1);
+            stream.Read(MemoryMarshal.AsBytes(spanT));
+
+            return structure;
+        }
+        #endregion
+
+        #region "GetSerializeSize"
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static int GetSerializeSizeDictionary<TKey, TValue>(Dictionary<TKey, TValue> dictionary, Func<TValue, int> valueFunc) where TKey : unmanaged
+        {
+            int size = 0;
+
+            size += Unsafe.SizeOf<int>();
+
+            foreach ((_, TValue value) in dictionary)
+            {
+                size += Unsafe.SizeOf<TKey>();
+                size += valueFunc(value);
+            }
+
+            return size;
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static int GetSerializeSizeList<T>(List<T> list) where T : unmanaged
+        {
+            int size = 0;
+
+            size += Unsafe.SizeOf<int>();
+
+            size += list.Count * Unsafe.SizeOf<T>();
+
+            return size;
+        }
+        #endregion
+
+        #region "Serialize"
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void SerializeDictionary<TKey, TValue>(Stream stream, Dictionary<TKey, TValue> dictionary, Action<Stream, TValue> valueAction) where TKey : unmanaged
+        {
+            SerializeStructure<int>(stream, dictionary.Count);
+
+            foreach ((TKey key, TValue value) in dictionary)
+            {
+                SerializeStructure<TKey>(stream, key);
+                valueAction(stream, value);
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void SerializeList<T>(Stream stream, List<T> list) where T : unmanaged
+        {
+            SerializeStructure<int>(stream, list.Count);
+
+            foreach (T item in list)
+            {
+                SerializeStructure<T>(stream, item);
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void SerializeStructure<T>(Stream stream, T structure) where T : unmanaged
+        {
+            Span<T> spanT = MemoryMarshal.CreateSpan(ref structure, 1);
+            stream.Write(MemoryMarshal.AsBytes(spanT));
+        }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/ARMeilleure/Translation/PTC/PtcInfo.cs b/ARMeilleure/Translation/PTC/PtcInfo.cs
index 547fe6d8..bbecb56f 100644
--- a/ARMeilleure/Translation/PTC/PtcInfo.cs
+++ b/ARMeilleure/Translation/PTC/PtcInfo.cs
@@ -9,7 +9,8 @@ namespace ARMeilleure.Translation.PTC
         private readonly BinaryWriter _relocWriter;
         private readonly BinaryWriter _unwindInfoWriter;
 
-        public MemoryStream CodeStream       { get; }
+        public byte[] Code { get; set; }
+
         public MemoryStream RelocStream      { get; }
         public MemoryStream UnwindInfoStream { get; }
 
@@ -17,7 +18,6 @@ namespace ARMeilleure.Translation.PTC
 
         public PtcInfo()
         {
-            CodeStream       = new MemoryStream();
             RelocStream      = new MemoryStream();
             UnwindInfoStream = new MemoryStream();
 
@@ -27,11 +27,6 @@ namespace ARMeilleure.Translation.PTC
             RelocEntriesCount = 0;
         }
 
-        public void WriteCode(MemoryStream codeStream)
-        {
-            codeStream.WriteTo(CodeStream);
-        }
-
         public void WriteRelocEntry(RelocEntry relocEntry)
         {
             _relocWriter.Write((int)relocEntry.Position);
@@ -60,7 +55,6 @@ namespace ARMeilleure.Translation.PTC
             _relocWriter.Dispose();
             _unwindInfoWriter.Dispose();
 
-            CodeStream.Dispose();
             RelocStream.Dispose();
             UnwindInfoStream.Dispose();
         }
diff --git a/ARMeilleure/Translation/PTC/PtcJumpTable.cs b/ARMeilleure/Translation/PTC/PtcJumpTable.cs
index d52d0874..75dcba50 100644
--- a/ARMeilleure/Translation/PTC/PtcJumpTable.cs
+++ b/ARMeilleure/Translation/PTC/PtcJumpTable.cs
@@ -6,15 +6,18 @@ using System.Diagnostics;
 using System.IO;
 using System.Runtime.InteropServices;
 
+using static ARMeilleure.Translation.PTC.PtcFormatter;
+
 namespace ARMeilleure.Translation.PTC
 {
     class PtcJumpTable
     {
+        [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 16*/)]
         public struct TableEntry<TAddress>
         {
             public int EntryIndex;
             public long GuestAddress;
-            public TAddress HostAddress;
+            public TAddress HostAddress; // int
 
             public TableEntry(int entryIndex, long guestAddress, TAddress hostAddress)
             {
@@ -24,14 +27,14 @@ namespace ARMeilleure.Translation.PTC
             }
         }
 
-        public enum DirectHostAddress
+        public enum DirectHostAddress : int
         {
             CallStub = 0,
             TailCallStub = 1,
             Host = 2
         }
 
-        public enum IndirectHostAddress
+        public enum IndirectHostAddress : int
         {
             CallStub = 0,
             TailCallStub = 1
@@ -66,152 +69,40 @@ namespace ARMeilleure.Translation.PTC
             Owners = owners;
         }
 
-        public static PtcJumpTable Deserialize(MemoryStream stream)
+        public static PtcJumpTable Deserialize(Stream stream)
         {
-            using (BinaryReader reader = new BinaryReader(stream, EncodingCache.UTF8NoBOM, true))
-            {
-                var jumpTable = new List<TableEntry<DirectHostAddress>>();
+            var jumpTable = DeserializeList<TableEntry<DirectHostAddress>>(stream);
+            var dynamicTable = DeserializeList<TableEntry<IndirectHostAddress>>(stream);
 
-                int jumpTableCount = reader.ReadInt32();
+            var targets = DeserializeList<ulong>(stream);
+            var dependants = DeserializeDictionary<ulong, List<int>>(stream, (stream) => DeserializeList<int>(stream));
+            var owners = DeserializeDictionary<ulong, List<int>>(stream, (stream) => DeserializeList<int>(stream));
 
-                for (int i = 0; i < jumpTableCount; i++)
-                {
-                    int entryIndex = reader.ReadInt32();
-                    long guestAddress = reader.ReadInt64();
-                    DirectHostAddress hostAddress = (DirectHostAddress)reader.ReadInt32();
-
-                    jumpTable.Add(new TableEntry<DirectHostAddress>(entryIndex, guestAddress, hostAddress));
-                }
-
-                var dynamicTable = new List<TableEntry<IndirectHostAddress>>();
-
-                int dynamicTableCount = reader.ReadInt32();
-
-                for (int i = 0; i < dynamicTableCount; i++)
-                {
-                    int entryIndex = reader.ReadInt32();
-                    long guestAddress = reader.ReadInt64();
-                    IndirectHostAddress hostAddress = (IndirectHostAddress)reader.ReadInt32();
-
-                    dynamicTable.Add(new TableEntry<IndirectHostAddress>(entryIndex, guestAddress, hostAddress));
-                }
-
-                var targets = new List<ulong>();
-
-                int targetsCount = reader.ReadInt32();
-
-                for (int i = 0; i < targetsCount; i++)
-                {
-                    ulong address = reader.ReadUInt64();
-
-                    targets.Add(address);
-                }
-
-                var dependants = new Dictionary<ulong, List<int>>();
-
-                int dependantsCount = reader.ReadInt32();
-
-                for (int i = 0; i < dependantsCount; i++)
-                {
-                    ulong address = reader.ReadUInt64();
-
-                    var entries = new List<int>();
-
-                    int entriesCount = reader.ReadInt32();
-
-                    for (int j = 0; j < entriesCount; j++)
-                    {
-                        int entry = reader.ReadInt32();
-
-                        entries.Add(entry);
-                    }
-
-                    dependants.Add(address, entries);
-                }
-
-                var owners = new Dictionary<ulong, List<int>>();
-
-                int ownersCount = reader.ReadInt32();
-
-                for (int i = 0; i < ownersCount; i++)
-                {
-                    ulong address = reader.ReadUInt64();
-
-                    var entries = new List<int>();
-
-                    int entriesCount = reader.ReadInt32();
-
-                    for (int j = 0; j < entriesCount; j++)
-                    {
-                        int entry = reader.ReadInt32();
-
-                        entries.Add(entry);
-                    }
-
-                    owners.Add(address, entries);
-                }
-
-                return new PtcJumpTable(jumpTable, dynamicTable, targets, dependants, owners);
-            }
+            return new PtcJumpTable(jumpTable, dynamicTable, targets, dependants, owners);
         }
 
-        public static void Serialize(MemoryStream stream, PtcJumpTable ptcJumpTable)
+        public static int GetSerializeSize(PtcJumpTable ptcJumpTable)
         {
-            using (BinaryWriter writer = new BinaryWriter(stream, EncodingCache.UTF8NoBOM, true))
-            {
-                writer.Write((int)ptcJumpTable._jumpTable.Count);
+            int size = 0;
 
-                foreach (var tableEntry in ptcJumpTable._jumpTable)
-                {
-                    writer.Write((int)tableEntry.EntryIndex);
-                    writer.Write((long)tableEntry.GuestAddress);
-                    writer.Write((int)tableEntry.HostAddress);
-                }
+            size += GetSerializeSizeList(ptcJumpTable._jumpTable);
+            size += GetSerializeSizeList(ptcJumpTable._dynamicTable);
 
-                writer.Write((int)ptcJumpTable._dynamicTable.Count);
+            size += GetSerializeSizeList(ptcJumpTable.Targets);
+            size += GetSerializeSizeDictionary(ptcJumpTable.Dependants, (list) => GetSerializeSizeList(list));
+            size += GetSerializeSizeDictionary(ptcJumpTable.Owners, (list) => GetSerializeSizeList(list));
 
-                foreach (var tableEntry in ptcJumpTable._dynamicTable)
-                {
-                    writer.Write((int)tableEntry.EntryIndex);
-                    writer.Write((long)tableEntry.GuestAddress);
-                    writer.Write((int)tableEntry.HostAddress);
-                }
+            return size;
+        }
 
-                writer.Write((int)ptcJumpTable.Targets.Count);
+        public static void Serialize(Stream stream, PtcJumpTable ptcJumpTable)
+        {
+            SerializeList(stream, ptcJumpTable._jumpTable);
+            SerializeList(stream, ptcJumpTable._dynamicTable);
 
-                foreach (ulong address in ptcJumpTable.Targets)
-                {
-                    writer.Write((ulong)address);
-                }
-
-                writer.Write((int)ptcJumpTable.Dependants.Count);
-
-                foreach (var kv in ptcJumpTable.Dependants)
-                {
-                    writer.Write((ulong)kv.Key); // address
-
-                    writer.Write((int)kv.Value.Count);
-
-                    foreach (int entry in kv.Value)
-                    {
-                        writer.Write((int)entry);
-                    }
-                }
-
-                writer.Write((int)ptcJumpTable.Owners.Count);
-
-                foreach (var kv in ptcJumpTable.Owners)
-                {
-                    writer.Write((ulong)kv.Key); // address
-
-                    writer.Write((int)kv.Value.Count);
-
-                    foreach (int entry in kv.Value)
-                    {
-                        writer.Write((int)entry);
-                    }
-                }
-            }
+            SerializeList(stream, ptcJumpTable.Targets);
+            SerializeDictionary(stream, ptcJumpTable.Dependants, (stream, list) => SerializeList(stream, list));
+            SerializeDictionary(stream, ptcJumpTable.Owners, (stream, list) => SerializeList(stream, list));
         }
 
         public void Initialize(JumpTable jumpTable)
@@ -270,14 +161,25 @@ namespace ARMeilleure.Translation.PTC
             Owners.Remove(guestAddress);
         }
 
-        public void Clear()
+        public void ClearIfNeeded()
         {
+            if (_jumpTable.Count == 0 && _dynamicTable.Count == 0 &&
+                Targets.Count == 0 && Dependants.Count == 0 && Owners.Count == 0)
+            {
+                return;
+            }
+
             _jumpTable.Clear();
+            _jumpTable.TrimExcess();
             _dynamicTable.Clear();
+            _dynamicTable.TrimExcess();
 
             Targets.Clear();
+            Targets.TrimExcess();
             Dependants.Clear();
+            Dependants.TrimExcess();
             Owners.Clear();
+            Owners.TrimExcess();
         }
 
         public void WriteJumpTable(JumpTable jumpTable, ConcurrentDictionary<ulong, TranslatedFunction> funcs)
@@ -307,7 +209,7 @@ namespace ARMeilleure.Translation.PTC
                     }
                     else
                     {
-                        if (!PtcProfiler.ProfiledFuncs.TryGetValue((ulong)guestAddress, out var value) || !value.highCq)
+                        if (!PtcProfiler.ProfiledFuncs.TryGetValue((ulong)guestAddress, out var value) || !value.HighCq)
                         {
                             throw new KeyNotFoundException($"({nameof(guestAddress)} = 0x{(ulong)guestAddress:X16})");
                         }
diff --git a/ARMeilleure/Translation/PTC/PtcProfiler.cs b/ARMeilleure/Translation/PTC/PtcProfiler.cs
index 0def32c3..8782a794 100644
--- a/ARMeilleure/Translation/PTC/PtcProfiler.cs
+++ b/ARMeilleure/Translation/PTC/PtcProfiler.cs
@@ -6,9 +6,12 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.IO.Compression;
+using System.Runtime.InteropServices;
 using System.Security.Cryptography;
 using System.Threading;
 
+using static ARMeilleure.Translation.PTC.PtcFormatter;
+
 namespace ARMeilleure.Translation.PTC
 {
     public static class PtcProfiler
@@ -29,7 +32,9 @@ namespace ARMeilleure.Translation.PTC
 
         private static bool _disposed;
 
-        internal static Dictionary<ulong, (ExecutionMode mode, bool highCq)> ProfiledFuncs { get; private set; }
+        private static byte[] _lastHash;
+
+        internal static Dictionary<ulong, FuncProfile> ProfiledFuncs { get; private set; }
 
         internal static bool Enabled { get; private set; }
 
@@ -47,7 +52,7 @@ namespace ARMeilleure.Translation.PTC
 
             _disposed = false;
 
-            ProfiledFuncs = new Dictionary<ulong, (ExecutionMode, bool)>();
+            ProfiledFuncs = new Dictionary<ulong, FuncProfile>();
 
             Enabled = false;
         }
@@ -60,7 +65,7 @@ namespace ARMeilleure.Translation.PTC
 
                 lock (_lock)
                 {
-                    ProfiledFuncs.TryAdd(address, (mode, highCq: false));
+                    ProfiledFuncs.TryAdd(address, new FuncProfile(mode, highCq: false));
                 }
             }
         }
@@ -75,7 +80,7 @@ namespace ARMeilleure.Translation.PTC
                 {
                     Debug.Assert(ProfiledFuncs.ContainsKey(address));
 
-                    ProfiledFuncs[address] = (mode, highCq: true);
+                    ProfiledFuncs[address] = new FuncProfile(mode, highCq: true);
                 }
             }
         }
@@ -95,7 +100,7 @@ namespace ARMeilleure.Translation.PTC
 
                 if (!funcs.ContainsKey(address))
                 {
-                    profiledFuncsToTranslate.Enqueue((address, profiledFunc.Value.mode, profiledFunc.Value.highCq));
+                    profiledFuncsToTranslate.Enqueue((address, profiledFunc.Value.Mode, profiledFunc.Value.HighCq));
                 }
             }
 
@@ -105,12 +110,15 @@ namespace ARMeilleure.Translation.PTC
         internal static void ClearEntries()
         {
             ProfiledFuncs.Clear();
+            ProfiledFuncs.TrimExcess();
         }
 
         internal static void PreLoad()
         {
-            string fileNameActual = String.Concat(Ptc.CachePathActual, ".info");
-            string fileNameBackup = String.Concat(Ptc.CachePathBackup, ".info");
+            _lastHash = Array.Empty<byte>();
+
+            string fileNameActual = string.Concat(Ptc.CachePathActual, ".info");
+            string fileNameBackup = string.Concat(Ptc.CachePathBackup, ".info");
 
             FileInfo fileInfoActual = new FileInfo(fileNameActual);
             FileInfo fileInfoBackup = new FileInfo(fileNameBackup);
@@ -138,8 +146,6 @@ namespace ARMeilleure.Translation.PTC
             using (MemoryStream stream = new MemoryStream())
             using (MD5 md5 = MD5.Create())
             {
-                int hashSize = md5.HashSize / 8;
-
                 try
                 {
                     deflateStream.CopyTo(stream);
@@ -151,6 +157,8 @@ namespace ARMeilleure.Translation.PTC
                     return false;
                 }
 
+                int hashSize = md5.HashSize / 8;
+
                 stream.Seek(0L, SeekOrigin.Begin);
 
                 byte[] currentHash = new byte[hashSize];
@@ -189,12 +197,14 @@ namespace ARMeilleure.Translation.PTC
                 }
                 catch
                 {
-                    ProfiledFuncs = new Dictionary<ulong, (ExecutionMode, bool)>();
+                    ProfiledFuncs = new Dictionary<ulong, FuncProfile>();
 
                     InvalidateCompressedStream(compressedStream);
 
                     return false;
                 }
+
+                _lastHash = expectedHash;
             }
 
             long fileSize = new FileInfo(fileName).Length;
@@ -209,7 +219,7 @@ namespace ARMeilleure.Translation.PTC
             return currentHash.SequenceEqual(expectedHash);
         }
 
-        private static Header ReadHeader(MemoryStream stream)
+        private static Header ReadHeader(Stream stream)
         {
             using (BinaryReader headerReader = new BinaryReader(stream, EncodingCache.UTF8NoBOM, true))
             {
@@ -223,26 +233,9 @@ namespace ARMeilleure.Translation.PTC
             }
         }
 
-        private static Dictionary<ulong, (ExecutionMode, bool)> Deserialize(MemoryStream stream)
+        private static Dictionary<ulong, FuncProfile> Deserialize(Stream stream)
         {
-            using (BinaryReader reader = new BinaryReader(stream, EncodingCache.UTF8NoBOM, true))
-            {
-                var profiledFuncs = new Dictionary<ulong, (ExecutionMode, bool)>();
-
-                int profiledFuncsCount = reader.ReadInt32();
-
-                for (int i = 0; i < profiledFuncsCount; i++)
-                {
-                    ulong address = reader.ReadUInt64();
-
-                    ExecutionMode mode = (ExecutionMode)reader.ReadInt32();
-                    bool highCq = reader.ReadBoolean();
-
-                    profiledFuncs.Add(address, (mode, highCq));
-                }
-
-                return profiledFuncs;
-            }
+            return DeserializeDictionary<ulong, FuncProfile>(stream, (stream) => DeserializeStructure<FuncProfile>(stream));
         }
 
         private static void InvalidateCompressedStream(FileStream compressedStream)
@@ -254,8 +247,8 @@ namespace ARMeilleure.Translation.PTC
         {
             _waitEvent.Reset();
 
-            string fileNameActual = String.Concat(Ptc.CachePathActual, ".info");
-            string fileNameBackup = String.Concat(Ptc.CachePathBackup, ".info");
+            string fileNameActual = string.Concat(Ptc.CachePathActual, ".info");
+            string fileNameBackup = string.Concat(Ptc.CachePathBackup, ".info");
 
             FileInfo fileInfoActual = new FileInfo(fileNameActual);
 
@@ -295,16 +288,25 @@ namespace ARMeilleure.Translation.PTC
                 stream.Seek(0L, SeekOrigin.Begin);
                 stream.Write(hash, 0, hashSize);
 
+                if (CompareHash(hash, _lastHash))
+                {
+                    return;
+                }
+
                 using (FileStream compressedStream = new FileStream(fileName, FileMode.OpenOrCreate))
                 using (DeflateStream deflateStream = new DeflateStream(compressedStream, SaveCompressionLevel, true))
                 {
                     try
                     {
                         stream.WriteTo(deflateStream);
+
+                        _lastHash = hash;
                     }
                     catch
                     {
                         compressedStream.Position = 0L;
+
+                        _lastHash = Array.Empty<byte>();
                     }
 
                     if (compressedStream.Position < compressedStream.Length)
@@ -316,10 +318,13 @@ namespace ARMeilleure.Translation.PTC
 
             long fileSize = new FileInfo(fileName).Length;
 
-            Logger.Info?.Print(LogClass.Ptc, $"Saved Profiling Info (size: {fileSize} bytes, profiled functions: {profiledFuncsCount}).");
+            if (fileSize != 0L)
+            {
+                Logger.Info?.Print(LogClass.Ptc, $"Saved Profiling Info (size: {fileSize} bytes, profiled functions: {profiledFuncsCount}).");
+            }
         }
 
-        private static void WriteHeader(MemoryStream stream)
+        private static void WriteHeader(Stream stream)
         {
             using (BinaryWriter headerWriter = new BinaryWriter(stream, EncodingCache.UTF8NoBOM, true))
             {
@@ -329,20 +334,9 @@ namespace ARMeilleure.Translation.PTC
             }
         }
 
-        private static void Serialize(MemoryStream stream, Dictionary<ulong, (ExecutionMode mode, bool highCq)> profiledFuncs)
+        private static void Serialize(Stream stream, Dictionary<ulong, FuncProfile> profiledFuncs)
         {
-            using (BinaryWriter writer = new BinaryWriter(stream, EncodingCache.UTF8NoBOM, true))
-            {
-                writer.Write((int)profiledFuncs.Count);
-
-                foreach (var kv in profiledFuncs)
-                {
-                    writer.Write((ulong)kv.Key); // address
-
-                    writer.Write((int)kv.Value.mode);
-                    writer.Write((bool)kv.Value.highCq);
-                }
-            }
+            SerializeDictionary(stream, profiledFuncs, (stream, structure) => SerializeStructure(stream, structure));
         }
 
         private struct Header
@@ -352,6 +346,19 @@ namespace ARMeilleure.Translation.PTC
             public uint InfoFileVersion;
         }
 
+        [StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 5*/)]
+        internal struct FuncProfile
+        {
+            public ExecutionMode Mode;
+            public bool HighCq;
+
+            public FuncProfile(ExecutionMode mode, bool highCq)
+            {
+                Mode = mode;
+                HighCq = highCq;
+            }
+        }
+
         internal static void Start()
         {
             if (Ptc.State == PtcState.Enabled ||
diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs
index ac96475f..f64912b3 100644
--- a/ARMeilleure/Translation/Translator.cs
+++ b/ARMeilleure/Translation/Translator.cs
@@ -11,8 +11,10 @@ using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
+using System.Runtime;
 using System.Threading;
 
+using static ARMeilleure.Common.BitMapPool;
 using static ARMeilleure.IntermediateRepresentation.OperandHelper;
 using static ARMeilleure.IntermediateRepresentation.OperationHelper;
 
@@ -148,10 +150,12 @@ namespace ARMeilleure.Translation
 
                 ClearJitCache();
 
-                ResetPools();
+                DisposePools();
 
                 _jumpTable.Dispose();
                 _jumpTable = null;
+
+                GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
             }
         }
 
@@ -207,7 +211,7 @@ namespace ARMeilleure.Translation
 
             Logger.EndPass(PassName.Decoding);
 
-            PreparePool(highCq);
+            PreparePool(highCq ? 1 : 0);
 
             Logger.StartPass(PassName.Translation);
 
@@ -240,13 +244,15 @@ namespace ARMeilleure.Translation
             {
                 func = Compiler.Compile<GuestFunction>(cfg, argTypes, OperandType.I64, options);
 
-                ReturnPool(highCq);
+                ResetPool(highCq ? 1 : 0);
             }
-            else using (PtcInfo ptcInfo = new PtcInfo())
+            else
             {
+                using PtcInfo ptcInfo = new PtcInfo();
+
                 func = Compiler.Compile<GuestFunction>(cfg, argTypes, OperandType.I64, options, ptcInfo);
 
-                ReturnPool(highCq);
+                ResetPool(highCq ? 1 : 0);
 
                 Ptc.WriteInfoCodeRelocUnwindInfo(address, funcSize, highCq, ptcInfo);
             }
@@ -254,22 +260,23 @@ namespace ARMeilleure.Translation
             return new TranslatedFunction(func, funcSize, highCq);
         }
 
-        internal static void PreparePool(bool highCq)
+        internal static void PreparePool(int groupId = 0)
         {
-            PrepareOperandPool(highCq);
-            PrepareOperationPool(highCq);
+            PrepareOperandPool(groupId);
+            PrepareOperationPool(groupId);
         }
 
-        internal static void ReturnPool(bool highCq)
+        internal static void ResetPool(int groupId = 0)
         {
-            ReturnOperandPool(highCq);
-            ReturnOperationPool(highCq);
+            ResetOperationPool(groupId);
+            ResetOperandPool(groupId);
         }
 
-        internal static void ResetPools()
+        internal static void DisposePools()
         {
-            ResetOperandPools();
-            ResetOperationPools();
+            DisposeOperandPools();
+            DisposeOperationPools();
+            DisposeBitMapPools();
         }
 
         private struct Range
diff --git a/Ryujinx.Memory/MemoryBlock.cs b/Ryujinx.Memory/MemoryBlock.cs
index 3b7a54ae..4e775bba 100644
--- a/Ryujinx.Memory/MemoryBlock.cs
+++ b/Ryujinx.Memory/MemoryBlock.cs
@@ -40,8 +40,6 @@ namespace Ryujinx.Memory
             }
 
             Size = size;
-
-            GC.AddMemoryPressure((long)Size);
         }
 
         /// <summary>
@@ -283,8 +281,6 @@ namespace Ryujinx.Memory
             if (ptr != IntPtr.Zero)
             {
                 MemoryManagement.Free(ptr);
-
-                GC.RemoveMemoryPressure((long)Size);
             }
         }