| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "ParserPch.h"
- #if ENABLE_REGEX_CONFIG_OPTIONS
- namespace UnifiedRegex
- {
- const char16* RegexStats::PhaseNames[RegexStats::NumPhases] = { _u("parse"), _u("compile"), _u("execute") };
- const char16* RegexStats::UseNames[RegexStats::NumUses] = { _u("match"), _u("exec"), _u("test"), _u("replace"), _u("split"), _u("search") };
- RegexStats::RegexStats(RegexPattern* pattern)
- : pattern(pattern)
- , inputLength(0)
- , numCompares(0)
- , numPushes(0)
- , numPops(0)
- , stackHWM(0)
- , numInsts(0)
- {
- for (int i = 0; i < NumPhases; i++)
- phaseTicks[i] = 0;
- for (int i = 0; i < NumUses; i++)
- useCounts[i] = 0;
- }
- void RegexStats::Print(DebugWriter* w, RegexStats* totals, Ticks ticksPerMillisecond)
- {
- if (pattern == 0)
- w->PrintEOL(_u("TOTAL"));
- else
- pattern->Print(w);
- w->EOL();
- w->Indent();
- for (int i = 0; i < NumPhases; i++)
- {
- double ms = (double)phaseTicks[i] / (double)ticksPerMillisecond;
- if (totals == 0 || totals->phaseTicks[i] == 0)
- w->PrintEOL(_u("%-12s: %10.4fms"), PhaseNames[i], ms);
- else
- {
- double pc = (double)phaseTicks[i] * 100.0 / (double)totals->phaseTicks[i];
- w->PrintEOL(_u("%-12s: %10.4fms (%10.4f%%)"), PhaseNames[i], ms, pc);
- }
- }
- for (int i = 0; i < NumUses; i++)
- {
- if (useCounts[i] > 0)
- {
- if (totals == 0 || totals->useCounts[i] == 0)
- w->PrintEOL(_u("#%-11s: %10I64u"), UseNames[i], useCounts[i]);
- else
- {
- double pc = (double)useCounts[i] * 100.0 / (double)totals->useCounts[i];
- w->PrintEOL(_u("#%-11s: %10I64u (%10.4f%%)"), UseNames[i], useCounts[i], pc);
- }
- }
- }
- if (inputLength > 0)
- {
- double r = (double)numCompares * 100.0 / (double)inputLength;
- if (totals == 0 || totals->numCompares == 0)
- w->PrintEOL(_u("numCompares : %10.4f%%"), r);
- else
- {
- double pc = (double)numCompares * 100.0 / (double)totals->numCompares;
- w->PrintEOL(_u("numCompares : %10.4f%% (%10.4f%%)"), r, pc);
- }
- }
- if (totals == 0 || totals->inputLength == 0)
- w->PrintEOL(_u("inputLength : %10I64u"), inputLength);
- else
- {
- double pc = (double)inputLength * 100.0 / (double)totals->inputLength;
- w->PrintEOL(_u("inputLength : %10I64u (%10.4f%%)"), inputLength, pc);
- }
- if (totals == 0 || totals->numPushes == 0)
- w->PrintEOL(_u("numPushes : %10I64u"), numPushes);
- else
- {
- double pc = (double)numPushes * 100.0 / (double)totals->numPushes;
- w->PrintEOL(_u("numPushes : %10I64u (%10.4f%%)"), numPushes, pc);
- }
- if (totals == 0 || totals->numPops == 0)
- w->PrintEOL(_u("numPops : %10I64u"), numPops);
- else
- {
- double pc = (double)numPops * 100.0 / (double)totals->numPops;
- w->PrintEOL(_u("numPops : %10I64u (%10.4f%%)"), numPops, pc);
- }
- if (totals == 0 || totals->stackHWM == 0)
- w->PrintEOL(_u("stackHWM : %10I64u"), stackHWM);
- else
- {
- double pc = (double)stackHWM * 100.0 / (double)totals->stackHWM;
- w->PrintEOL(_u("stackHWM : %10I64u (%10.4f%%)"), stackHWM, pc);
- }
- if (totals == 0 || totals->numInsts == 0)
- w->PrintEOL(_u("numInsts : %10I64u"), numInsts);
- else
- {
- double pc = (double)numInsts * 100.0 / (double)totals->numInsts;
- w->PrintEOL(_u("numInsts : %10I64u (%10.4f%%)"), numInsts, pc);
- }
- w->Unindent();
- }
- void RegexStats::Add(RegexStats* other)
- {
- for (int i = 0; i < NumPhases; i++)
- phaseTicks[i] += other->phaseTicks[i];
- for (int i = 0; i < NumUses; i++)
- useCounts[i] += other->useCounts[i];
- inputLength += other->inputLength;
- numCompares += other->numCompares;
- numPushes += other->numPushes;
- numPops += other->numPops;
- if (other->stackHWM > stackHWM)
- stackHWM = other->stackHWM;
- numInsts += other->numInsts;
- }
- RegexStats::Ticks RegexStatsDatabase::Now()
- {
- LARGE_INTEGER tmp;
- if (QueryPerformanceCounter(&tmp))
- return tmp.QuadPart;
- else
- {
- Assert(false);
- return 0;
- }
- }
- RegexStats::Ticks RegexStatsDatabase::Freq()
- {
- LARGE_INTEGER tmp;
- if (QueryPerformanceFrequency(&tmp))
- {
- return tmp.QuadPart / 1000;
- }
- else
- {
- Assert(false);
- return 1;
- }
- }
- RegexStatsDatabase::RegexStatsDatabase(ArenaAllocator* allocator)
- : start(0), allocator(allocator)
- {
- ticksPerMillisecond = Freq();
- map = Anew(allocator, RegexStatsMap, allocator, 17);
- }
- RegexStats* RegexStatsDatabase::GetRegexStats(RegexPattern* pattern)
- {
- Js::InternalString str = pattern->GetSource();
- RegexStats *res;
- if (!map->TryGetValue(str, &res))
- {
- res = Anew(allocator, RegexStats, pattern);
- map->Add(str, res);
- }
- return res;
- }
- void RegexStatsDatabase::BeginProfile()
- {
- start = Now();
- }
- void RegexStatsDatabase::EndProfile(RegexStats* stats, RegexStats::Phase phase)
- {
- stats->phaseTicks[phase] += Now() - start;
- }
- void RegexStatsDatabase::Print(DebugWriter* w)
- {
- RegexStats totals(0);
- Output::Print(_u("Regular Expression Statistics\n"));
- Output::Print(_u("=============================\n"));
- for (int i = 0; i < map->Count(); i++)
- totals.Add(map->GetValueAt(i));
- for (int i = 0; i < map->Count(); i++)
- map->GetValueAt(i)->Print(w, &totals, ticksPerMillisecond);
- totals.Print(w, 0, ticksPerMillisecond);
- allocator->Free(w, sizeof(DebugWriter));
- }
- }
- #endif
|