Improve performance with calling regex less often

This commit is contained in:
Infi
2024-05-08 23:16:51 +02:00
parent d0212023eb
commit 53cf79003b
+46 -29
View File
@@ -131,7 +131,7 @@ internal class Message
return Guid.Empty; return Guid.Empty;
} }
private List<Chunk> CheckMessageContent(List<Chunk> content) private List<Chunk> CheckMessageContent(List<Chunk> oldChunks)
{ {
var newChunks = new List<Chunk>(); var newChunks = new List<Chunk>();
void AddChunkWithMessage(Chunk chunk) void AddChunkWithMessage(Chunk chunk)
@@ -140,7 +140,44 @@ internal class Message
newChunks.Add(chunk); newChunks.Add(chunk);
} }
foreach (var chunk in content) void AddContentAfterURLCheck(string content, TextChunk text, Chunk chunk)
{
// This works because c# will split regex string, while keeping named groups as separated splits
// If the match is the first content of a string, the array will start with a ""
// Same if 2 matches are next to each other, they will be split with a ""
var splits = URLRegex.Split(content);
if (splits.Length == 1)
{
AddChunkWithMessage(text.NewWithStyle(chunk.Source, chunk.Link, content));
return;
}
var nextIsMatch = false;
foreach (var split in splits)
{
if (split == "" || !nextIsMatch)
{
nextIsMatch = true;
AddChunkWithMessage(text.NewWithStyle(chunk.Source, chunk.Link, split));
continue;
}
// Create a new TextChunk with a URIPayload for the URL text.
nextIsMatch = false;
try
{
var link = UriPayload.ResolveURI(split);
AddChunkWithMessage(text.NewWithStyle(chunk.Source, link, split));
}
catch (UriFormatException)
{
AddChunkWithMessage(text.NewWithStyle(chunk.Source, chunk.Link, split));
Plugin.Log.Debug($"Invalid URL accepted by Regex but failed URI parsing: '{split}'");
}
}
}
foreach (var chunk in oldChunks)
{ {
// Use as is if it's not a text chunk or it already has a payload. // Use as is if it's not a text chunk or it already has a payload.
if (chunk is not TextChunk text || chunk.Link != null) if (chunk is not TextChunk text || chunk.Link != null)
@@ -151,46 +188,26 @@ internal class Message
continue; continue;
} }
// We replace every emote before checking for URLs
var builder = new StringBuilder(); var builder = new StringBuilder();
foreach (var word in text.Content.Split(" ")) foreach (var word in text.Content.Split(" "))
{ {
if (EmoteCache.Exists(word)) if (EmoteCache.Exists(word))
{ {
// We add all the previous collected text parts // We add all the previous collected text parts
AddChunkWithMessage(text.NewWithStyle(chunk.Source, chunk.Link, builder.ToString())); AddContentAfterURLCheck(builder.ToString(), text, chunk);
builder.Clear(); builder.Clear();
newChunks.Add(new TextChunk(chunk.Source, EmotePayload.ResolveEmote(word), "Cool BetterTTV")); newChunks.Add(new TextChunk(chunk.Source, EmotePayload.ResolveEmote(word), word));
builder.Append(' '); builder.Append(' ');
continue; continue;
} }
if (URLRegex.IsMatch(word))
{
// We add all the previous collected text parts
AddChunkWithMessage(text.NewWithStyle(chunk.Source, chunk.Link, builder.ToString()));
builder.Clear();
// Create a new TextChunk with a URIPayload for the URL text.
try
{
var link = UriPayload.ResolveURI(word);
AddChunkWithMessage(text.NewWithStyle(chunk.Source, link, word));
builder.Append(' ');
continue;
}
catch (UriFormatException)
{
Plugin.Log.Debug($"Invalid URL accepted by Regex but failed URI parsing: '{word}'");
}
}
builder.Append($"{word} "); builder.Append($"{word} ");
} }
// We add the leftovers // We add the leftovers
AddChunkWithMessage(text.NewWithStyle(chunk.Source, chunk.Link, builder.ToString()[..^1])); // Removing the last whitespace as it is set by us
AddContentAfterURLCheck(builder.ToString()[..^1], text, chunk);
} }
return newChunks; return newChunks;
@@ -209,7 +226,7 @@ internal class Message
/// without a prefix on specific TLDs. /// without a prefix on specific TLDs.
/// </summary> /// </summary>
private static Regex URLRegex = new( private static Regex URLRegex = new(
@"((https?:\/\/|www\.)[a-z0-9-]+(\.[a-z0-9-]+)*|([a-z0-9-]+(\.[a-z0-9-]+)*\.(com|net|org|co|io|app)))(:[\d]{1,5})?(\/[^\s]+)?", @"(?<URL>((https?:\/\/|www\.)[a-z0-9-]+(\.[a-z0-9-]+)*|([a-z0-9-]+(\.[a-z0-9-]+)*\.(com|net|org|co|io|app)))(:[\d]{1,5})?(\/[^\s]+)?)",
RegexOptions.Compiled | RegexOptions.IgnoreCase RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture
); );
} }