HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Why is this code to paste into a DataGridView so slow?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thiswhyintodatagridviewslowpastecode

Problem

string s = Clipboard.GetText().Replace("\r", " ");
string[] lines = s.Split('\n');
int row = dgView.CurrentCell.RowIndex;
int col = dgView.CurrentCell.ColumnIndex;
int linesCount = lines.Count();
if ((row + linesCount) - dgView.RowCount > 0) dgView.Rows.Add((row + linesCount) - dgView.RowCount);

asyncSqlResultsViewer.publicToolStripProgressBar.Maximum = linesCount;
asyncSqlResultsViewer.publicToolStripProgressBar.Step = 1;
asyncSqlResultsViewer.publicToolStripProgressBar.Visible = true;
dgView.ReadOnly = true;

foreach (string line in lines)
{
    if (line.Length > 0)
    {
        string[] cells = line.Split('\t');
        for (int i = 0; i < cells.GetLength(0); ++i)
        {
            if (col + i < dgView.ColumnCount)
            {
                dgView[col + i, row].Value = cells[i];
            }
            else
            {
                break;
            }
        }
        row++;
    }
    else
    {
        break;
    }
    asyncSqlResultsViewer.publicToolStripProgressBar.PerformStep();
}


It is ridiculously slow. Pasting 500 rows with 5 columns takes about 30 seconds. Please take into consideration that there might be already data in the DataGridView and I don't necessarily want to override it (it all depends on the starting cell). So I don't know how could I use a DataTable and assign it as DataSource in case you had that idea.

Solution

I wasn't convinced that the code per se, besides what could be done to improve it, would take this long under 'normal' circumstances. I thought I'd actually test this myself before bed and so threw something together, here's what I did...

I created a WinForms application with the appropriate controls and then used a Stopwatch, only modifying your code (forgetting names of controls) by placing it in a method named PasteData which returned lineCount:

private readonly Stopwatch stopWatch = new Stopwatch();

private int PasteData()
{
    //Your code.
}

private void dataGridView_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.V)
    {
        int linesExisting = dataGridView.RowCount;
        stopWatch.Restart();
        int linesPasted = PasteData();
        stopWatch.Stop();
        TimeSpan timeElapsed = stopWatch.Elapsed;

        //UI Updates.
    }
    e.Handled = true;
}


I fired up excel and created 700+ rows of data; 5 columns of random text pasted repeatedly:


Axdcfg vkhjbkljhgvf hghbjkl;jbhg vguyhjknjhbgvyhjknb hkghjlkh,njjk;olkm,nhn
ghvbnmkl;kknjbhvghcgv gbhnmkknkjhbghfvghjkljhgfvhjklhbgvhkjlmnjbhgfcfgyhjknlmnn
ghvjbkmjnhyuiytui89766890i09u8y675tfvghbjnmkl,;m,nbhh
tf678cfghjbkm,.g90u87ygybihuionjhgvfctfygyuhio;jolkkjnhbvfc
iouy43212345678987654321234567890009876543212w3erfghgfdffcv

I then copied the whole collection from the clipboard and proceeded to flood our application with it up to a count of almost 300,000 rows, and here are the results:

Performance degradation was absolutely negligible. If anything, it was the amount of memory being consumed that was to become a concern.

Do you have any more specific information regarding your predicament? We need to define you 'normal' circumstances. The format and nature of the test data would be nice to know, ideally a sample could be supplied. You could define expected amounts of data that the view might contain. Also, some hardware details, here's some of my basic info:

  • RAM: 2.00GB



  • Processor: AMD Turion 64 X2 TL-60 2.0Ghz



  • OS: Windows 7 Ultimate 64bit

Code Snippets

private readonly Stopwatch stopWatch = new Stopwatch();

private int PasteData()
{
    //Your code.
}

private void dataGridView_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.V)
    {
        int linesExisting = dataGridView.RowCount;
        stopWatch.Restart();
        int linesPasted = PasteData();
        stopWatch.Stop();
        TimeSpan timeElapsed = stopWatch.Elapsed;

        //UI Updates.
    }
    e.Handled = true;
}

Context

StackExchange Code Review Q#2042, answer score: 3

Revisions (0)

No revisions yet.