Skip to content

Commit 999a0f8

Browse files
committed
Fix a performance bug
1 parent d088fce commit 999a0f8

File tree

3 files changed

+29
-24
lines changed

3 files changed

+29
-24
lines changed

src/SIL.Machine.Morphology.HermitCrab/AnalysisStratumRule.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public IEnumerable<Word> Apply(Word input)
6767
if (_morpher.TraceManager.IsTracing)
6868
_morpher.TraceManager.BeginUnapplyStratum(_stratum, input);
6969

70+
Word origInput = input;
7071
input = input.Clone();
7172
input.Stratum = _stratum;
7273

@@ -89,11 +90,13 @@ public IEnumerable<Word> Apply(Word input)
8990
{
9091
if (mergeEquivalentAnalyses)
9192
{
93+
// Skip intermediate sources from phonological rules, templates, and morphological rules.
94+
mruleOutWord.Source = origInput;
9295
Shape shape = mruleOutWord.Shape;
9396
if (shapeWord.ContainsKey(shape))
9497
{
9598
shapeWord[shape].Alternatives.Add(mruleOutWord);
96-
continue;
99+
continue;
97100
}
98101
shapeWord[shape] = mruleOutWord;
99102
}

src/SIL.Machine.Morphology.HermitCrab/Morpher.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,13 @@ public IEnumerable<Word> ParseWord(string word, out object trace, bool guessRoot
146146
var lexicalGuesses = LexicalGuess(analysisWord).Distinct();
147147
foreach (Word synthesisWord in lexicalGuesses)
148148
{
149-
foreach (Word validWord in _synthesisRule.Apply(synthesisWord).Where(IsWordValid))
149+
foreach (Word alternative in synthesisWord.ExpandAlternatives())
150150
{
151-
if (IsMatch(word, validWord))
152-
matches.Add(validWord);
151+
foreach (Word validWord in _synthesisRule.Apply(alternative).Where(IsWordValid))
152+
{
153+
if (IsMatch(word, validWord))
154+
matches.Add(validWord);
155+
}
153156
}
154157
}
155158
}
@@ -285,10 +288,13 @@ private IEnumerable<Word> Synthesize(string word, IEnumerable<Word> analyses)
285288
{
286289
foreach (Word synthesisWord in LexicalLookup(analysisWord))
287290
{
288-
foreach (Word validWord in _synthesisRule.Apply(synthesisWord).Where(IsWordValid))
291+
foreach (Word alternative in synthesisWord.ExpandAlternatives())
289292
{
290-
if (IsMatch(word, validWord))
291-
matches.Add(validWord);
293+
foreach (Word validWord in _synthesisRule.Apply(alternative).Where(IsWordValid))
294+
{
295+
if (IsMatch(word, validWord))
296+
matches.Add(validWord);
297+
}
292298
}
293299
}
294300
}
@@ -311,9 +317,9 @@ private IEnumerable<Word> Synthesize(string word, ConcurrentQueue<Word> analyses
311317
analyses.TryDequeue(out Word analysisWord);
312318
foreach (Word synthesisWord in LexicalLookup(analysisWord))
313319
{
314-
foreach (Word alternativeSynthesis in synthesisWord.ExpandAlternatives())
320+
foreach (Word alternative in synthesisWord.ExpandAlternatives())
315321
{
316-
foreach (Word validWord in _synthesisRule.Apply(alternativeSynthesis).Where(IsWordValid))
322+
foreach (Word validWord in _synthesisRule.Apply(alternative).Where(IsWordValid))
317323
{
318324
if (IsMatch(word, validWord))
319325
matches.Add(validWord);

src/SIL.Machine.Morphology.HermitCrab/Word.cs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ public class Word : Freezable<Word>, IAnnotatedData<ShapeNode>, ICloneable<Word>
3131
private bool _isPartial;
3232
private readonly Dictionary<string, HashSet<int>> _disjunctiveAllomorphIndices;
3333
private int _mruleAppCount = 0;
34-
private readonly Word _cloneOf = null;
3534
private readonly IList<Word> _alternatives = new List<Word>();
3635

3736
public Word(RootAllomorph rootAllomorph, FeatureStruct realizationalFS)
@@ -74,6 +73,8 @@ protected Word(Word word)
7473
{
7574
_allomorphs = new Dictionary<string, Allomorph>(word._allomorphs);
7675
Stratum = word.Stratum;
76+
Source = word;
77+
// Don't copy Alternatives.
7778
_shape = word._shape.Clone();
7879
_rootAllomorph = word._rootAllomorph;
7980
SyntacticFeatureStruct = word.SyntacticFeatureStruct.Clone();
@@ -94,7 +95,6 @@ protected Word(Word word)
9495
kvp => new HashSet<int>(kvp.Value)
9596
);
9697
_mruleAppCount = word._mruleAppCount;
97-
_cloneOf = word;
9898
}
9999

100100
public IEnumerable<Annotation<ShapeNode>> Morphs
@@ -399,10 +399,7 @@ internal void NonHeadUnapplied(Word nonHead)
399399
_nonHeadAppIndex++;
400400
}
401401

402-
internal Word CloneOf
403-
{
404-
get { return _cloneOf; }
405-
}
402+
internal Word Source { get; set; }
406403

407404
internal IList<Word> Alternatives
408405
{
@@ -412,8 +409,8 @@ internal IList<Word> Alternatives
412409
internal IList<Word> ExpandAlternatives()
413410
{
414411
IList<Word> alternatives = new List<Word>();
415-
IList<Word> originals = _cloneOf?.ExpandAlternatives();
416-
// Update the alternatives of _cloneOf with any changes made since the clone.
412+
IList<Word> originals = Source?.ExpandAlternatives();
413+
// Update the alternatives of CloneOf with any changes made since the clone.
417414
if (originals == null || originals.Count < 2)
418415
{
419416
// Special case.
@@ -426,18 +423,17 @@ internal IList<Word> ExpandAlternatives()
426423
Word alternative = original.Clone();
427424
alternative._shape = this.Shape;
428425
// Add new rules to alternative.
429-
foreach (IMorphologicalRule rule in MorphologicalRules)
430-
{
431-
if (_cloneOf != null && _cloneOf.MorphologicalRules.Contains(rule))
432-
continue;
433-
alternative.MorphologicalRuleUnapplied(rule);
434-
}
426+
int m_start = Source == null ? 0 : Source._mruleApps.Count();
427+
for (int i = m_start; i < _mruleApps.Count(); i++)
428+
alternative.MorphologicalRuleUnapplied(_mruleApps[i]);
429+
int nh_start = Source == null ? 0 : Source._nonHeadApps.Count();
430+
for (int i = nh_start; i < _nonHeadApps.Count(); i++)
431+
alternative.NonHeadUnapplied(_nonHeadApps[i]);
435432
if (RootAllomorph != null)
436433
alternative.RootAllomorph = RootAllomorph;
437434
alternative.Freeze();
438435
alternatives.Add(alternative);
439436
}
440-
441437
}
442438
// Add local alternatives.
443439
foreach (Word alternative in _alternatives)

0 commit comments

Comments
 (0)