perf: minimize temporary strings for better performance (#1255)

This commit is contained in:
qiufengshe 2025-04-29 09:33:14 +08:00 committed by GitHub
parent 53a55467f1
commit 48bb8e91de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 35 additions and 23 deletions

View file

@ -1,4 +1,4 @@
using System; using System;
using System.IO; using System.IO;
using Avalonia.Data.Converters; using Avalonia.Data.Converters;
@ -22,7 +22,7 @@ namespace SourceGit.Converters
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length; var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length;
if (v.StartsWith(home, StringComparison.Ordinal)) if (v.StartsWith(home, StringComparison.Ordinal))
return "~" + v.Substring(prefixLen); return $"~{v.AsSpan().Slice(prefixLen)}";
return v; return v;
}); });

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -147,9 +148,9 @@ namespace SourceGit.Models
public void GenerateNewPatchFromSelection(Change change, string fileBlobGuid, TextDiffSelection selection, bool revert, string output) public void GenerateNewPatchFromSelection(Change change, string fileBlobGuid, TextDiffSelection selection, bool revert, string output)
{ {
var isTracked = !string.IsNullOrEmpty(fileBlobGuid); var isTracked = !string.IsNullOrEmpty(fileBlobGuid);
var fileGuid = isTracked ? fileBlobGuid.Substring(0, 8) : "00000000"; var fileGuid = isTracked ? fileBlobGuid.AsSpan().Slice(0, 8) : "00000000".AsSpan();
var builder = new StringBuilder(); var builder = new StringBuilder(512);
builder.Append("diff --git a/").Append(change.Path).Append(" b/").Append(change.Path).Append('\n'); builder.Append("diff --git a/").Append(change.Path).Append(" b/").Append(change.Path).Append('\n');
if (!revert && !isTracked) if (!revert && !isTracked)
builder.Append("new file mode 100644\n"); builder.Append("new file mode 100644\n");

View file

@ -1,4 +1,5 @@
using CommunityToolkit.Mvvm.ComponentModel; using System;
using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.Models namespace SourceGit.Models
{ {
@ -22,12 +23,12 @@ namespace SourceGit.Models
get get
{ {
if (IsDetached) if (IsDetached)
return $"deteched HEAD at {Head.Substring(10)}"; return $"deteched HEAD at {Head.AsSpan().Slice(10)}";
if (Branch.StartsWith("refs/heads/", System.StringComparison.Ordinal)) if (Branch.StartsWith("refs/heads/", StringComparison.Ordinal))
return Branch.Substring(11); return Branch.Substring(11);
if (Branch.StartsWith("refs/remotes/", System.StringComparison.Ordinal)) if (Branch.StartsWith("refs/remotes/", StringComparison.Ordinal))
return Branch.Substring(13); return Branch.Substring(13);
return Branch; return Branch;

View file

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations; using System;
using System.ComponentModel.DataAnnotations;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -31,7 +32,7 @@ namespace SourceGit.ViewModels
{ {
_repo = repo; _repo = repo;
_revision = commit.SHA; _revision = commit.SHA;
_saveFile = $"archive-{commit.SHA.Substring(0, 10)}.zip"; _saveFile = $"archive-{commit.SHA.AsSpan().Slice(0, 10)}.zip";
BasedOn = commit; BasedOn = commit;
} }

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Threading; using Avalonia.Threading;
@ -30,7 +31,7 @@ namespace SourceGit.ViewModels
{ {
_repo = repo; _repo = repo;
Title = $"{file} @ {revision.Substring(0, 10)}"; Title = $"{file} @ {revision.AsSpan().Slice(0, 10)}";
Task.Run(() => Task.Run(() =>
{ {
var result = new Commands.Blame(repo, file, revision).Result(); var result = new Commands.Blame(repo, file, revision).Result();

View file

@ -1,4 +1,4 @@
using System; using System;
using System.IO; using System.IO;
using Avalonia.Collections; using Avalonia.Collections;
@ -584,7 +584,7 @@ namespace SourceGit.ViewModels
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length; var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length;
if (path.StartsWith(home, StringComparison.Ordinal)) if (path.StartsWith(home, StringComparison.Ordinal))
path = "~" + path.Substring(prefixLen); path = $"~{path.AsSpan().Slice(prefixLen)}";
} }
Title = $"[{workspace}] {name} ({path})"; Title = $"[{workspace}] {name} ({path})";

View file

@ -205,7 +205,7 @@ namespace SourceGit.Views
foreach (var item in selected) foreach (var item in selected)
{ {
if (item is Models.Commit commit) if (item is Models.Commit commit)
builder.AppendLine($"{commit.SHA.Substring(0, 10)} - {commit.Subject}"); builder.AppendLine($"{commit.SHA.AsSpan().Slice(0, 10)} - {commit.Subject}");
} }
App.CopyText(builder.ToString()); App.CopyText(builder.ToString());

View file

@ -126,7 +126,7 @@ namespace SourceGit.Views
typeface, typeface,
presenter.FontSize, presenter.FontSize,
presenter.Foreground); presenter.Foreground);
context.DrawText(txt, new Point(Bounds.Width - txt.Width, y - txt.Height * 0.5)); context.DrawText(txt, new Point(Bounds.Width - txt.Width, y - (txt.Height * 0.5)));
} }
} }
} }
@ -212,7 +212,7 @@ namespace SourceGit.Views
} }
if (indicator != null) if (indicator != null)
context.DrawText(indicator, new Point(0, y - indicator.Height * 0.5)); context.DrawText(indicator, new Point(0, y - (indicator.Height * 0.5)));
} }
} }
} }
@ -1047,7 +1047,8 @@ namespace SourceGit.Views
// The first selected line (partial selection) // The first selected line (partial selection)
if (i == startIdx && startPosition.Column > 1) if (i == startIdx && startPosition.Column > 1)
{ {
builder.AppendLine(line.Content.Substring(startPosition.Column - 1)); builder.Append(line.Content.AsSpan().Slice(startPosition.Column - 1));
builder.Append(Environment.NewLine);
continue; continue;
} }
@ -1061,7 +1062,14 @@ namespace SourceGit.Views
// For the last line (selection range is within original source) // For the last line (selection range is within original source)
if (i == endIdx) if (i == endIdx)
{ {
builder.Append(endPosition.Column - 1 < line.Content.Length ? line.Content.Substring(0, endPosition.Column - 1) : line.Content); if (endPosition.Column - 1 < line.Content.Length)
{
builder.Append(line.Content.AsSpan().Slice(0, endPosition.Column - 1));
}
else
{
builder.Append(line.Content);
}
break; break;
} }
@ -1246,12 +1254,12 @@ namespace SourceGit.Views
var textDiff = DataContext as Models.TextDiff; var textDiff = DataContext as Models.TextDiff;
if (textDiff != null) if (textDiff != null)
{ {
var builder = new StringBuilder(); var builder = new StringBuilder(512);
foreach (var line in textDiff.Lines) foreach (var line in textDiff.Lines)
{ {
if (line.Content.Length > 10000) if (line.Content.Length > 10000)
{ {
builder.Append(line.Content.Substring(0, 1000)); builder.Append(line.Content.AsSpan().Slice(0, 1000));
builder.Append($"...({line.Content.Length - 1000} character trimmed)"); builder.Append($"...({line.Content.Length - 1000} character trimmed)");
} }
else else
@ -1741,7 +1749,7 @@ namespace SourceGit.Views
} }
var top = chunk.Y + (chunk.Height >= 36 ? 16 : 4); var top = chunk.Y + (chunk.Height >= 36 ? 16 : 4);
var right = (chunk.Combined || !chunk.IsOldSide) ? 16 : v.Bounds.Width * 0.5f + 16; var right = (chunk.Combined || !chunk.IsOldSide) ? 16 : (v.Bounds.Width * 0.5f) + 16;
v.Popup.Margin = new Thickness(0, top, right, 0); v.Popup.Margin = new Thickness(0, top, right, 0);
v.Popup.IsVisible = true; v.Popup.IsVisible = true;
}); });