mmanela / diffplex

DiffPlex is Netstandard 1.0+ C# library to generate textual diffs.
Apache License 2.0
979 stars 182 forks source link

Loading of Large File Hangs #93

Open ajardolino3 opened 2 years ago

ajardolino3 commented 2 years ago

I am creating a DiffViewer control (WindowsForms) just like the demo code. Works fine with small files, but when I have a file that has a few thousand lines, it hangs for a while. Eventually it loads, but it just takes forever. Not sure what is wrong. Can this be fixed please?

mmanela commented 2 years ago

Is the delay from the core lib or the UI control?

Drake53 commented 1 year ago

I have the same issue (using DiffPlex.Wpf v1.3.1 in my NET5 winforms application).

The files that I tested were 40k lines of JSON. The loading appears to happen during form.ShowDialog(), and when I try SideBySideDiffBuilder.Diff() it completes pretty much instantly, so it seems to me that the delay is in the UI control. (it also slowly consumes more and more RAM, up to around 2GB before I run out and have to kill the process in task manager)

Looks like the same issue as here: https://github.com/mmanela/diffplex/issues/87

lanboss commented 1 year ago

i try, WebDiffer is fast, DiffPlex.Wpf is slow , InsertLinesAsync method is slowly , InternalLinesViewer ->StackPanel add
VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.IsVirtualizing="True" will not slow when drag,but load file still slow

lanboss commented 1 year ago

i solute the question , changed InsertLinesAsync method private static async Task InsertLinesAsync(Guid guid, InternalLinesViewer panel, List<DiffPiece> lines, bool isOld, UIElement source, int contextLineCount) { // For performance. if (lines == null || panel == null) return; var disablePieces = lines.Count > MaxCount; var i = 100; if (panel.TrackingId != guid) return; InsertLinesInteral(panel, lines.Take(i).ToList(), isOld, source, disablePieces); while (i < lines.Count) { //await Task.Delay(i > 5000 ? 1000 : 800); if (panel.TrackingId != guid) return; await panel.Dispatcher.BeginInvoke(() => { InsertLinesInteral(panel, lines.Skip(i).Take(100).ToList(), isOld, source, disablePieces); }, DispatcherPriority.Background); i += 100; } if (contextLineCount > -1) CollapseUnchangedSections(panel, contextLineCount); } 2 points: 500-> 100 Invoke ->BeginInvoke ,thread level is DispatcherPriority.Background

lanboss commented 1 year ago
    private static async Task InsertLinesAsync(Guid guid, InternalLinesViewer panel, List<DiffPiece> lines, bool isOld, UIElement source, int contextLineCount)
    {   // For performance.
        if (lines == null || panel == null) return;
        var disablePieces = lines.Count > MaxCount;
        var i = 100;
        if (panel.TrackingId != guid) return;
        InsertLinesInteral(panel, lines.Take(i).ToList(), isOld, source, disablePieces);
        while (i < lines.Count)
        {
            //await Task.Delay(i > 5000 ? 1000 : 800);
            if (panel.TrackingId != guid) return;
           await panel.Dispatcher.BeginInvoke(() =>
            {
                InsertLinesInteral(panel, lines.Skip(i).Take(100).ToList(), isOld, source, disablePieces);
            }, DispatcherPriority.Background);
            i += 100;
        }
        if (contextLineCount > -1) CollapseUnchangedSections(panel, contextLineCount);
    }