Skip to content

Commit

Permalink
Fix a performance bug
Browse files Browse the repository at this point in the history
  • Loading branch information
jtmaxwell3 committed Jan 21, 2025
1 parent d088fce commit 999a0f8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 24 deletions.
5 changes: 4 additions & 1 deletion src/SIL.Machine.Morphology.HermitCrab/AnalysisStratumRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public IEnumerable<Word> Apply(Word input)
if (_morpher.TraceManager.IsTracing)
_morpher.TraceManager.BeginUnapplyStratum(_stratum, input);

Word origInput = input;
input = input.Clone();
input.Stratum = _stratum;

Expand All @@ -89,11 +90,13 @@ public IEnumerable<Word> Apply(Word input)
{
if (mergeEquivalentAnalyses)
{
// Skip intermediate sources from phonological rules, templates, and morphological rules.
mruleOutWord.Source = origInput;
Shape shape = mruleOutWord.Shape;
if (shapeWord.ContainsKey(shape))
{
shapeWord[shape].Alternatives.Add(mruleOutWord);
continue;
continue;
}
shapeWord[shape] = mruleOutWord;
}
Expand Down
22 changes: 14 additions & 8 deletions src/SIL.Machine.Morphology.HermitCrab/Morpher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,13 @@ public IEnumerable<Word> ParseWord(string word, out object trace, bool guessRoot
var lexicalGuesses = LexicalGuess(analysisWord).Distinct();
foreach (Word synthesisWord in lexicalGuesses)
{
foreach (Word validWord in _synthesisRule.Apply(synthesisWord).Where(IsWordValid))
foreach (Word alternative in synthesisWord.ExpandAlternatives())
{
if (IsMatch(word, validWord))
matches.Add(validWord);
foreach (Word validWord in _synthesisRule.Apply(alternative).Where(IsWordValid))
{
if (IsMatch(word, validWord))
matches.Add(validWord);
}
}
}
}
Expand Down Expand Up @@ -285,10 +288,13 @@ private IEnumerable<Word> Synthesize(string word, IEnumerable<Word> analyses)
{
foreach (Word synthesisWord in LexicalLookup(analysisWord))
{
foreach (Word validWord in _synthesisRule.Apply(synthesisWord).Where(IsWordValid))
foreach (Word alternative in synthesisWord.ExpandAlternatives())
{
if (IsMatch(word, validWord))
matches.Add(validWord);
foreach (Word validWord in _synthesisRule.Apply(alternative).Where(IsWordValid))
{
if (IsMatch(word, validWord))
matches.Add(validWord);
}
}
}
}
Expand All @@ -311,9 +317,9 @@ private IEnumerable<Word> Synthesize(string word, ConcurrentQueue<Word> analyses
analyses.TryDequeue(out Word analysisWord);
foreach (Word synthesisWord in LexicalLookup(analysisWord))
{
foreach (Word alternativeSynthesis in synthesisWord.ExpandAlternatives())
foreach (Word alternative in synthesisWord.ExpandAlternatives())
{
foreach (Word validWord in _synthesisRule.Apply(alternativeSynthesis).Where(IsWordValid))
foreach (Word validWord in _synthesisRule.Apply(alternative).Where(IsWordValid))
{
if (IsMatch(word, validWord))
matches.Add(validWord);
Expand Down
26 changes: 11 additions & 15 deletions src/SIL.Machine.Morphology.HermitCrab/Word.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public class Word : Freezable<Word>, IAnnotatedData<ShapeNode>, ICloneable<Word>
private bool _isPartial;
private readonly Dictionary<string, HashSet<int>> _disjunctiveAllomorphIndices;
private int _mruleAppCount = 0;
private readonly Word _cloneOf = null;
private readonly IList<Word> _alternatives = new List<Word>();

public Word(RootAllomorph rootAllomorph, FeatureStruct realizationalFS)
Expand Down Expand Up @@ -74,6 +73,8 @@ protected Word(Word word)
{
_allomorphs = new Dictionary<string, Allomorph>(word._allomorphs);
Stratum = word.Stratum;
Source = word;
// Don't copy Alternatives.
_shape = word._shape.Clone();
_rootAllomorph = word._rootAllomorph;
SyntacticFeatureStruct = word.SyntacticFeatureStruct.Clone();
Expand All @@ -94,7 +95,6 @@ protected Word(Word word)
kvp => new HashSet<int>(kvp.Value)
);
_mruleAppCount = word._mruleAppCount;
_cloneOf = word;
}

public IEnumerable<Annotation<ShapeNode>> Morphs
Expand Down Expand Up @@ -399,10 +399,7 @@ internal void NonHeadUnapplied(Word nonHead)
_nonHeadAppIndex++;
}

internal Word CloneOf
{
get { return _cloneOf; }
}
internal Word Source { get; set; }

internal IList<Word> Alternatives
{
Expand All @@ -412,8 +409,8 @@ internal IList<Word> Alternatives
internal IList<Word> ExpandAlternatives()
{
IList<Word> alternatives = new List<Word>();
IList<Word> originals = _cloneOf?.ExpandAlternatives();
// Update the alternatives of _cloneOf with any changes made since the clone.
IList<Word> originals = Source?.ExpandAlternatives();
// Update the alternatives of CloneOf with any changes made since the clone.
if (originals == null || originals.Count < 2)
{
// Special case.
Expand All @@ -426,18 +423,17 @@ internal IList<Word> ExpandAlternatives()
Word alternative = original.Clone();
alternative._shape = this.Shape;
// Add new rules to alternative.
foreach (IMorphologicalRule rule in MorphologicalRules)
{
if (_cloneOf != null && _cloneOf.MorphologicalRules.Contains(rule))
continue;
alternative.MorphologicalRuleUnapplied(rule);
}
int m_start = Source == null ? 0 : Source._mruleApps.Count();
for (int i = m_start; i < _mruleApps.Count(); i++)
alternative.MorphologicalRuleUnapplied(_mruleApps[i]);
int nh_start = Source == null ? 0 : Source._nonHeadApps.Count();
for (int i = nh_start; i < _nonHeadApps.Count(); i++)
alternative.NonHeadUnapplied(_nonHeadApps[i]);
if (RootAllomorph != null)
alternative.RootAllomorph = RootAllomorph;
alternative.Freeze();
alternatives.Add(alternative);
}

}
// Add local alternatives.
foreach (Word alternative in _alternatives)
Expand Down

0 comments on commit 999a0f8

Please sign in to comment.