') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Add a JsonNode roundtrip benchmark by eiriktsarpalis · Pull Request #2714 · dotnet/performance · GitHub
Skip to content

Add a JsonNode roundtrip benchmark - #2714

Merged
eiriktsarpalis merged 1 commit into
dotnet:mainfrom
eiriktsarpalis:add-jsonnode-benchmark
Nov 11, 2022
Merged

Add a JsonNode roundtrip benchmark#2714
eiriktsarpalis merged 1 commit into
dotnet:mainfrom
eiriktsarpalis:add-jsonnode-benchmark

Conversation

@eiriktsarpalis

Copy link
Copy Markdown
Member

We don't have any benchmarks tracking JsonNode performance, adding one here. Should help us catch performance regressions like the one reported in dotnet/runtime#78089.

.NET 7

MethodIsDataIndentedTestCaseMeanErrorStdDevMedianMinMaxGen 0Gen 1Gen 2Allocated
ParseThenWriteFalseHelloWorld1.629 us0.1034 us0.1191 us1.631 us1.445 us1.861 us0.11270.00590.00591.21 KB
ParseThenWriteFalseDeepTree71.814 us5.7978 us6.6767 us71.981 us61.361 us83.650 us3.92610.46190.230941.39 KB
ParseThenWriteFalseBroadTree143.157 us9.4310 us10.8607 us144.141 us124.357 us161.210 us7.69231.09890.549585.58 KB
ParseThenWriteFalseLotsOfNumbers33.528 us3.2085 us3.4331 us33.050 us28.688 us40.852 us1.8508--20.65 KB
ParseThenWriteFalseLotsOfStrings30.900 us2.3209 us2.6727 us30.905 us25.774 us36.619 us1.65720.11840.118417.37 KB
ParseThenWriteFalseJson400B13.306 us1.0877 us1.2526 us13.080 us11.222 us15.969 us0.71890.04790.04797.54 KB
ParseThenWriteFalseJson4KB98.384 us5.3244 us5.9181 us97.605 us87.727 us109.771 us5.32480.71000.355055.93 KB
ParseThenWriteFalseJson400KB11,597.244 us1,219.7139 us1,305.0802 us11,788.595 us9,782.182 us14,438.336 us545.4545454.545590.90915419.64 KB
ParseThenWriteTrueHelloWorld1.652 us0.0918 us0.1058 us1.640 us1.475 us1.908 us0.11120.00620.00621.2 KB
ParseThenWriteTrueDeepTree79.871 us5.4731 us6.3029 us79.029 us69.537 us91.046 us4.16670.55560.277844.28 KB
ParseThenWriteTrueBroadTree127.201 us8.7583 us9.3713 us127.193 us114.161 us147.240 us8.22371.64470.548287.66 KB
ParseThenWriteTrueLotsOfNumbers33.675 us2.3780 us2.7385 us34.034 us27.549 us39.641 us1.99600.12480.124820.93 KB
ParseThenWriteTrueLotsOfStrings30.747 us1.8929 us2.1799 us30.955 us25.725 us34.167 us1.6681--17.75 KB
ParseThenWriteTrueJson400B13.257 us0.9355 us1.0774 us13.175 us11.739 us15.118 us0.69600.04640.04647.65 KB
ParseThenWriteTrueJson4KB96.272 us7.9884 us9.1994 us93.730 us78.500 us111.757 us5.40540.72070.360456.99 KB
ParseThenWriteTrueJson400KB10,162.729 us732.9558 us814.6784 us10,055.850 us8,930.960 us11,691.760 us500.0000400.0000100.00005543.76 KB

.NET 8 (after fix)

MethodIsDataIndentedTestCaseMeanErrorStdDevMedianMinMaxGen 0Gen 1Gen 2Allocated
ParseThenWriteFalseHelloWorld611.4 ns19.22 ns20.56 ns609.1 ns577.1 ns647.6 ns0.0702--712 B
ParseThenWriteFalseDeepTree30,617.2 ns1,239.33 ns1,326.07 ns30,430.6 ns27,339.7 ns33,301.3 ns2.1149--22192 B
ParseThenWriteFalseBroadTree52,627.7 ns2,671.54 ns3,076.55 ns52,192.6 ns47,220.4 ns58,579.6 ns4.20170.4202-43216 B
ParseThenWriteFalseLotsOfNumbers13,226.7 ns734.68 ns846.05 ns13,009.4 ns11,974.5 ns15,061.0 ns1.0400--10784 B
ParseThenWriteFalseLotsOfStrings7,290.9 ns317.29 ns365.39 ns7,300.4 ns6,686.2 ns8,056.4 ns0.5378--5480 B
ParseThenWriteFalseJson400B5,196.0 ns252.67 ns280.85 ns5,206.3 ns4,710.1 ns5,748.4 ns0.4109--4240 B
ParseThenWriteFalseJson4KB36,775.5 ns1,880.67 ns2,012.30 ns37,072.4 ns32,836.0 ns40,909.0 ns2.74980.1528-28504 B
ParseThenWriteFalseJson400KB6,355,027.6 ns597,473.16 ns664,089.84 ns6,320,892.1 ns5,047,955.3 ns7,476,928.9 ns315.7895263.1579105.26322803212 B
ParseThenWriteTrueHelloWorld655.1 ns25.97 ns28.86 ns658.6 ns608.7 ns709.1 ns0.0699--712 B
ParseThenWriteTrueDeepTree39,053.1 ns2,295.58 ns2,643.59 ns38,891.6 ns34,736.8 ns44,070.4 ns2.37180.1482-24992 B
ParseThenWriteTrueBroadTree56,388.3 ns1,863.04 ns2,070.77 ns56,406.7 ns51,892.5 ns61,454.6 ns4.32700.4555-45352 B
ParseThenWriteTrueLotsOfNumbers13,440.2 ns471.28 ns504.26 ns13,381.9 ns12,777.5 ns14,620.3 ns1.0434--11072 B
ParseThenWriteTrueLotsOfStrings8,390.4 ns358.16 ns412.46 ns8,255.7 ns7,722.6 ns9,254.7 ns0.5560--5792 B
ParseThenWriteTrueJson400B5,224.6 ns178.13 ns197.99 ns5,224.6 ns4,984.9 ns5,672.0 ns0.4225--4336 B
ParseThenWriteTrueJson4KB38,281.5 ns1,744.40 ns2,008.85 ns37,902.4 ns35,839.9 ns41,678.9 ns2.79410.1471-29536 B
ParseThenWriteTrueJson400KB5,878,425.8 ns1,287,095.94 ns1,482,221.60 ns5,264,561.1 ns4,362,961.1 ns8,828,844.4 ns222.2222111.111155.55562906385 B

Comment on lines +40 to +47
if (!IsDataIndented)
{
_dataUtf8 = DocumentHelpers.RemoveFormatting(jsonString);
}
else
{
_dataUtf8 = Encoding.UTF8.GetBytes(jsonString);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!IsDataIndented)
{
_dataUtf8=DocumentHelpers.RemoveFormatting(jsonString);
}
else
{
_dataUtf8=Encoding.UTF8.GetBytes(jsonString);
}
_dataUtf8=IsDataIndented?
Encoding.UTF8.GetBytes(jsonString):
DocumentHelpers.RemoveFormatting(jsonString);

?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initialization code is copypasta'd from the equivalent JsonDocument benchmark (also called ParseThenWrite.cs).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initialization code is copypasta'd from the equivalent

FWIW Setup and cleanup code can be always refactored and improved (duplicated code moved to helper type), as changing it typically does not affect the benchmark itself

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@eiriktsarpalis@stephentoub@adamsitnik