diff --git a/Calculator/Math/Unit.cs b/Calculator/Math/Unit.cs
index 8650907..d219015 100644
--- a/Calculator/Math/Unit.cs
+++ b/Calculator/Math/Unit.cs
@@ -1,17 +1,8 @@
-using System.Collections.Generic;
-using System.Collections.Immutable;
+using System.Collections.Immutable;
 
 namespace Calculator.Math;
 
 public sealed record Unit(string ShortName, ImmutableArray<string> LongNames) {
-	internal void AssignNamesTo(Dictionary<string, Unit> nameToUnitDictionary) {
-		nameToUnitDictionary.Add(ShortName, this);
-
-		foreach (string longName in LongNames) {
-			nameToUnitDictionary.Add(longName, this);
-		}
-	}
-
 	public override string ToString() {
 		return ShortName;
 	}
diff --git a/Calculator/Math/UnitUniverse.cs b/Calculator/Math/UnitUniverse.cs
index e324913..5ae9d33 100644
--- a/Calculator/Math/UnitUniverse.cs
+++ b/Calculator/Math/UnitUniverse.cs
@@ -10,7 +10,6 @@ using ExtendedNumerics;
 namespace Calculator.Math;
 
 sealed class UnitUniverse(
-	Unit primaryUnit,
 	FrozenDictionary<Unit, Func<Number, Number>> unitToConversionToPrimaryUnit,
 	FrozenDictionary<Unit, Func<Number, Number>> unitToConversionFromPrimaryUnit
 ) {
@@ -61,9 +60,9 @@ sealed class UnitUniverse(
 	}
 
 	internal sealed class Builder {
+		private readonly Unit primaryUnit;
 		private readonly Dictionary<Unit, Func<Number, Number>> unitToConversionToPrimaryUnit = new (ReferenceEqualityComparer.Instance);
 		private readonly Dictionary<Unit, Func<Number, Number>> unitToConversionFromPrimaryUnit = new (ReferenceEqualityComparer.Instance);
-		private readonly Unit primaryUnit;
 
 		public Builder(Unit primaryUnit) {
 			this.primaryUnit = primaryUnit;
@@ -113,7 +112,6 @@ sealed class UnitUniverse(
 
 		public UnitUniverse Build() {
 			return new UnitUniverse(
-				primaryUnit,
 				unitToConversionToPrimaryUnit.ToFrozenDictionary(ReferenceEqualityComparer.Instance),
 				unitToConversionFromPrimaryUnit.ToFrozenDictionary(ReferenceEqualityComparer.Instance)
 			);
diff --git a/Calculator/Math/UnitUniverses.cs b/Calculator/Math/UnitUniverses.cs
index b75d837..48e9b3b 100644
--- a/Calculator/Math/UnitUniverses.cs
+++ b/Calculator/Math/UnitUniverses.cs
@@ -1,4 +1,5 @@
-using System.Collections.Frozen;
+using System;
+using System.Collections.Frozen;
 using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
 
@@ -6,28 +7,72 @@ namespace Calculator.Math;
 
 sealed class UnitUniverses {
 	private readonly FrozenDictionary<Unit, UnitUniverse> unitToUniverse;
-	private readonly FrozenDictionary<string, Unit> nameToUnit;
+	
+	public WordLookupTrieNode UnitLookupByWords { get; }
 
 	internal UnitUniverses(params UnitUniverse[] universes) {
 		Dictionary<Unit, UnitUniverse> unitToUniverseBuilder = new (ReferenceEqualityComparer.Instance);
-		Dictionary<string, Unit> nameToUnitBuilder = new ();
-
+		WordLookupTrieNode.Builder unitLookupByWordsBuilder = new ();
+		
 		foreach (UnitUniverse universe in universes) {
 			foreach (Unit unit in universe.AllUnits) {
 				unitToUniverseBuilder.Add(unit, universe);
-				unit.AssignNamesTo(nameToUnitBuilder);
+				unitLookupByWordsBuilder.Add(unit);
 			}
 		}
 
 		unitToUniverse = unitToUniverseBuilder.ToFrozenDictionary(ReferenceEqualityComparer.Instance);
-		nameToUnit = nameToUnitBuilder.ToFrozenDictionary();
-	}
-	
-	public bool TryGetUnit(string name, [NotNullWhen(true)] out Unit? unit) {
-		return nameToUnit.TryGetValue(name, out unit);
+		UnitLookupByWords = unitLookupByWordsBuilder.Build();
 	}
 	
 	public bool TryGetUniverse(Unit unit, [NotNullWhen(true)] out UnitUniverse? universe) {
 		return unitToUniverse.TryGetValue(unit, out universe);
 	}
+	
+	public sealed record WordLookupTrieNode(Unit? Unit, FrozenDictionary<string, WordLookupTrieNode> Children) {
+		internal sealed class Builder {
+			private sealed record Node(Unit? Unit, Dictionary<string, Node> Children) {
+				internal static Node Create(Unit? unit = null) {
+					return new Node(unit, new Dictionary<string, Node>());
+				}
+				
+				internal Node Child(string word) {
+					if (!Children.TryGetValue(word, out Node? child)) {
+						Children.Add(word, child = Create());
+					}
+					
+					return child;
+				}
+			}
+			
+			private readonly Node root = Node.Create();
+			
+			public void Add(Unit unit) {
+				Add(unit.ShortName, unit);
+				
+				foreach (string longName in unit.LongNames) {
+					Add(longName, unit);
+				}
+			}
+			
+			private void Add(string name, Unit unit) {
+				Node node = root;
+				string[] words = name.Split(' ');
+
+				foreach (string word in words.AsSpan(..^1)) {
+					node = node.Child(word);
+				}
+				
+				node.Children.Add(words[^1], Node.Create(unit));
+			}
+
+			public WordLookupTrieNode Build() {
+				return Build(root);
+			}
+			
+			private WordLookupTrieNode Build(Node node) {
+				return new WordLookupTrieNode(node.Unit, node.Children.ToFrozenDictionary(static kvp => kvp.Key, kvp => Build(kvp.Value)));
+			}
+		}
+	}
 }
diff --git a/Calculator/Parser/Parser.cs b/Calculator/Parser/Parser.cs
index 90ad5ec..707752a 100644
--- a/Calculator/Parser/Parser.cs
+++ b/Calculator/Parser/Parser.cs
@@ -1,8 +1,6 @@
 using System;
-using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.Diagnostics.CodeAnalysis;
-using System.Linq;
 using Calculator.Math;
 
 namespace Calculator.Parser;
@@ -189,25 +187,23 @@ public sealed class Parser(ImmutableArray<Token> tokens) {
 
 	private bool MatchUnit([NotNullWhen(true)] out Unit? unit) {
 		int position = current;
-		
-		List<string> words = [];
-		
-		while (Match(out Token.Text? text)) {
-			words.Add(text.Value);
+
+		UnitUniverses.WordLookupTrieNode node = Units.All.UnitLookupByWords;
+
+		// ReSharper disable once AccessToModifiedClosure
+		while (Match(token => node.Children.ContainsKey(token.Value), out Token.Text? text)) {
+			node = node.Children[text.Value];
 		}
 
-		for (int i = words.Count; i > 0; i--) {
-			string unitName = string.Join(' ', words.Take(i));
+		unit = node.Unit;
 
-			if (Units.All.TryGetUnit(unitName, out unit)) {
-				current = position + i;
-				return true;
-			}
+		if (unit != null) {
+			return true;
+		}
+		else {
+			current = position;
+			return false;
 		}
-
-		current = position;
-		unit = null;
-		return false;
 	}
 
 	private bool MatchUnitConversionOperator() {