Find-and-Replace double-quotes in a 3000 line C# verbatim string literal is very slow
Repro steps:
- Running LinqPad 7 Premium, v7.4.9 x64.
- Create a new query, "C# Statement(s)" mode.
Declare an empty const string verbatim literal on line 1:
const String TEST_STRING = @"";
Put the caret between the two double-quotes in
@""
and press[Return]
twice.Paste a large string which already contains its own (single) double-quote characters, such as a JSON object.
- In my case, see the attached
computedStyleObject.txt
file (a Firefox console dump ofwindow.getComputedStyle()
. Copy and paste the contents of the file into the empty line inside the@""
string literal.
- In my case, see the attached
After pasting (which should be instantaneous) then select the text you just pasted (i.e. select from column 0 on line 2 (from
"-moz-animation..."
) through to the end"
inzIndex: "auto"
on line 2838.Press Ctrl+H to open Find-and-Replace.
- Find What:
"
(i.e. find single double-quote characters) - Replace with:
""
(i.e. replace with double-double-quote characters) - [x] Search in selection
- Find What:
Click "Replace All"
- Observe that Linqpad freezes and locks-up for a good while...
The circled CPU usage chart in Task Manager corresponds to Linqpad being frozen and eventually un-freezing. Interesting shape... also interesting that a good chunk is spent in kernel mode too.
Comments
I would be tempted to say that using a 3000 line string in code is asking for trouble, but I still would not have expected it to be that bad. I have no idea why this would take so long but perhaps it is trying to re-parse the string after every replacement, rather than once at the end.
Coding editors, parsers and compilers are not usually optimised to handle such long strings. I read recently that the Go language have added an embed statement which I think is to avoid issues like this.
There are a few things you can do to minimise the problem.
It would probably be much much faster if the file was opened in Linqpad as a Text file and the replacements were done there.
It should be even faster to do this in code i.e.
System.IO.File.ReadAllText("...\\computedStyleObject.txt").Replace("\"", "\"\"").Dump();
And yes, I know this is not as convenient if the text is already in the clipboard.
Also, do you know about Alt-Shift-V , 'Paste as Escaped string' option?
I'll improve this in the next build - it should get down to a few seconds for that many replacements. Also note the suggestion of @sgmoore regarding Paste as Escaped string.
Also note that should the file be larger - 30,000 lines, for instance - you'll run into other editor limitations and will need to read the JSON directly from the filesystem.