{"article":{"slug":"speeding-up-the-unreal-editor-by-not-using-unnecessarily-secure-hash-methods","title":"Speeding up the Unreal editor by… not using unnecessarily secure hash methods","subtitle":null,"summary":"A profiling write-up finding that Unreal Engine's editor launch hashes full shader source files with cryptographically secure SHA-1, and how switching to the engine's existing xxHash implementation sped this up, plus notes on preparing the change as a pull request.","content_type":"blog_post","language":"en","canonical_url":"https://larstofus.com/2026/10/11/speeding-up-the-unreal-editor-by-not-using-unnecessarily-secure-hash-methods/","author":{"name":"Lars Thiessen","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Larst Of Us","url":"https://larstofus.com/","listing_slug":null,"listing":null},"topics":[{"name":"Performance","slug":"performance","url":"https://listedarticles.com/topics/performance"},{"name":"Programming","slug":"programming","url":"https://listedarticles.com/topics/programming"},{"name":"Engineering","slug":"engineering","url":"https://listedarticles.com/topics/engineering"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":986,"reading_minutes":4,"published_at":"2026-10-11T18:41:20.000Z","added_at":"2026-10-12T20:24:01.846Z","updated_at":"2026-10-12T20:24:01.846Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/speeding-up-the-unreal-editor-by-not-using-unnecessarily-secure-hash-methods","markdown_url":"https://listedarticles.com/articles/speeding-up-the-unreal-editor-by-not-using-unnecessarily-secure-hash-methods.md","example":false,"citation":"Lars Thiessen, Larst Of Us. \"Speeding up the Unreal editor by… not using unnecessarily secure hash methods.\" 11 Oct 2026. https://larstofus.com/2026/10/11/speeding-up-the-unreal-editor-by-not-using-unnecessarily-secure-hash-methods/ (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://larstofus.com/2026/10/11/speeding-up-the-unreal-editor-by-not-using-unnecessarily-secure-hash-methods/"},"body_markdown":"One good trick when trying to look for ways to optimize software is to stay away from areas that are very likely already quite well optimized, and instead focus on areas that might have been overlooked, either because they are too obscure or don’t show up during regular profiling sessions. This tactic worked well in the past, as shown with my optimization of [tooltip creation](https://larstofus.com/2025/09/02/speeding-up-the-unreal-editor-launch-by-not-spawning-38000-tooltips/), or the loading of [editor localization files](https://larstofus.com/2025/09/02/speeding-up-the-unreal-editor-launch-by-not-spawning-38000-tooltips/).\n\nSo when profiling the editor launch (again), this is why I mostly skip over any functions that contain words like “Shader Compilation” or “Shader Source” when I stumble over them in my profiler. The compilation of shaders is a famously long and elaborate process, and I’m pretty sure that very smart people at Epic already spent a lot of time optimizing those areas. That’s the reason why I would, for example, skip the function “Compile Global Shader Map,” even though its runtime would be typically multiple seconds:\n\n![](https://larstofus.com/wp-content/uploads/2026/10/image.png?w=581)\n\nThis was, at least, true until one day I skipped over it using an unusually high zoom level and saw one of the functions that was called by it:\n\n![](https://larstofus.com/wp-content/uploads/2026/10/image-1.png?w=622)\n\nI am certainly not an expert for hash algorithms, but SHA1 is one of the (very few) hash algorithms that even I know. And seeing this hash algorithm being used to hash shaders seemed somehow wrong to me. That’s because [SHA1](https://en.wikipedia.org/wiki/SHA-1) ~~is~~ was a cryptographically safe hashing algorithm, originally developed by the NSA (yes, that one). And even though it has been cryptographically  broken years ago and actually shouldn’t be used for sensitive information anymore, this origin means that it is – to put it politely – not particularly fast.  \nWhat does not fast mean in this context? Well see for yourself in this [comparison test](https://aras-p.info/blog/2016/08/09/More-Hash-Function-Tests/) of a bunch of commonly used hash algorithms that Aras Pranckevičius did a few years ago (actually, it was 10 years ago – I’m getting old). SHA1 was not even included as an actual competitor, but as the start of the article notes just “to illustrate the performance differences.” Ouch.  \nThat’s especially annoying since the data being hashed is the shader source code, including all comments and copyright notice:\n\n![](https://larstofus.com/wp-content/uploads/2026/10/image-3.png?w=799)\n\nThis means both that we have to hash a lot of data (source files can be quite big) and that there is no reason to hash it using a cryptographically secure hash, since it is no sensitive data.\n\nTherefore, not using a cryptographically safe but fast hash algorithm should be an easy win, right? And the linked article already presented a good alternative, for which I even found an existing implementation in Unreal’s code base: xxHash.\n\nNote before somebody asks: xxHash is not necessarily the fastest hash. Other, potentially even faster hashes [do exist,](https://aras-p.info/blog/2026/03/07/Rapidhash-Unity-port/) but for now, using a faster hash that is already a used and tested part of the engine we are working on is a much more straightforward option.   \nChanging the used hash wasn’t too complicated, even though I had to change more places in the code than expected, since all places where the produced hash was stored or passed also had to be updated. A nice side effect of this change was that the stored hashes were a bit smaller than before (8 instead of 20 bytes).  \nBut, of course, the effect that I made the change for wasn’t about memory, but CPU time. For testing purposes, I opened one of Unreal’s own sample projects, [Electric Dreams](https://www.fab.com/listings/d79688f5-29be-4fb2-a650-2d4a813f5306?lang=en), in the editor 5 times, both with and without the change, for a total of 10 runs. Profiling was done with [Superluminal](https://superluminal.eu/).\n\n![](https://larstofus.com/wp-content/uploads/2026/10/image-4.png?w=1024)\n\nTo put the following numbers into perspective, let me note that I will mostly talk about the overall CPU time, summed up over all threads, not just the time on the game thread. This is not done to artificially inflate the numbers, but to make the numbers more consistent and easier to compare. The actual effect on the editor start time is (very roughly) the measured time divided by the number of cores.\n\nIn the vanilla version of the engine, a whopping 12.90 seconds were spent in FSHA1::Update. In the modified version using xxHash, this time shrunk to just 1.59 seconds spent in FXxHash64Builder::Update. That’s eight times faster! Mission accomplished.\n\nNormally, this article would now end with a link to a pull request so that anybody interested in the change could integrate it into their own version of the engine while we wait and hope that somebody at Epic would see the pull request and merge it into the main branch.  \nWell, this time I have even better news: The change already got accepted! (not merged however, this seems still to take a few days more)  \nI submitted the [pull request](https://github.com/EpicGames/UnrealEngine/pull/15237) just a few days before writing this article and those few days were already enough for somebody at Epic to not only review my change but also polish it up. So let’s take a look some of the changes that were done to my proposed change:  \nOne very smart feat that I hadn’t thought of was to wrap the xxHash into another struct, FShaderHash. This doesn’t change the behavior right now but will make it easier to change the hash algorithm again in the future if an even faster one is needed without changing the code in many different places.  \nFixed a compile error for non-editor builds: That was an oversight on my sight. I had only tested my change in an editor build, mainly because my original profiling was also done in editor. I might need to add non-editor builds to my growing list of checks to do before a pull request in the future.  \nAnd that was it. If you enjoyed this article and want to read more about game optimization in the future, consider following me on [BlueSky](https://bsky.app/profile/larstofus.bsky.social), [Mastodon](https://mastodon.gamedev.place/@LarsThiessen) or [Linkedin](http://www.linkedin.com/in/larstofus) where I post all my articles. Or subscribe directly to my blog right below the article.\n","body_html":"<p>One good trick when trying to look for ways to optimize software is to stay away from areas that are very likely already quite well optimized, and instead focus on areas that might have been overlooked, either because they are too obscure or don’t show up during regular profiling sessions. This tactic worked well in the past, as shown with my optimization of <a href=\"https://larstofus.com/2025/09/02/speeding-up-the-unreal-editor-launch-by-not-spawning-38000-tooltips/\" rel=\"nofollow ugc noopener\">tooltip creation</a>, or the loading of <a href=\"https://larstofus.com/2025/09/02/speeding-up-the-unreal-editor-launch-by-not-spawning-38000-tooltips/\" rel=\"nofollow ugc noopener\">editor localization files</a>.</p>\n<p>So when profiling the editor launch (again), this is why I mostly skip over any functions that contain words like “Shader Compilation” or “Shader Source” when I stumble over them in my profiler. The compilation of shaders is a famously long and elaborate process, and I’m pretty sure that very smart people at Epic already spent a lot of time optimizing those areas. That’s the reason why I would, for example, skip the function “Compile Global Shader Map,” even though its runtime would be typically multiple seconds:</p>\n<figure><img src=\"https://larstofus.com/wp-content/uploads/2026/10/image.png?w=581\" alt=\"\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>This was, at least, true until one day I skipped over it using an unusually high zoom level and saw one of the functions that was called by it:</p>\n<figure><img src=\"https://larstofus.com/wp-content/uploads/2026/10/image-1.png?w=622\" alt=\"\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>I am certainly not an expert for hash algorithms, but SHA1 is one of the (very few) hash algorithms that even I know. And seeing this hash algorithm being used to hash shaders seemed somehow wrong to me. That’s because <a href=\"https://en.wikipedia.org/wiki/SHA-1\" rel=\"nofollow ugc noopener\">SHA1</a> <del>is</del> was a cryptographically safe hashing algorithm, originally developed by the NSA (yes, that one). And even though it has been cryptographically  broken years ago and actually shouldn’t be used for sensitive information anymore, this origin means that it is – to put it politely – not particularly fast.<br />\nWhat does not fast mean in this context? Well see for yourself in this <a href=\"https://aras-p.info/blog/2016/08/09/More-Hash-Function-Tests/\" rel=\"nofollow ugc noopener\">comparison test</a> of a bunch of commonly used hash algorithms that Aras Pranckevičius did a few years ago (actually, it was 10 years ago – I’m getting old). SHA1 was not even included as an actual competitor, but as the start of the article notes just “to illustrate the performance differences.” Ouch.<br />\nThat’s especially annoying since the data being hashed is the shader source code, including all comments and copyright notice:</p>\n<figure><img src=\"https://larstofus.com/wp-content/uploads/2026/10/image-3.png?w=799\" alt=\"\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>This means both that we have to hash a lot of data (source files can be quite big) and that there is no reason to hash it using a cryptographically secure hash, since it is no sensitive data.</p>\n<p>Therefore, not using a cryptographically safe but fast hash algorithm should be an easy win, right? And the linked article already presented a good alternative, for which I even found an existing implementation in Unreal’s code base: xxHash.</p>\n<p>Note before somebody asks: xxHash is not necessarily the fastest hash. Other, potentially even faster hashes <a href=\"https://aras-p.info/blog/2026/03/07/Rapidhash-Unity-port/\" rel=\"nofollow ugc noopener\">do exist,</a> but for now, using a faster hash that is already a used and tested part of the engine we are working on is a much more straightforward option.<br />\nChanging the used hash wasn’t too complicated, even though I had to change more places in the code than expected, since all places where the produced hash was stored or passed also had to be updated. A nice side effect of this change was that the stored hashes were a bit smaller than before (8 instead of 20 bytes).<br />\nBut, of course, the effect that I made the change for wasn’t about memory, but CPU time. For testing purposes, I opened one of Unreal’s own sample projects, <a href=\"https://www.fab.com/listings/d79688f5-29be-4fb2-a650-2d4a813f5306?lang=en\" rel=\"nofollow ugc noopener\">Electric Dreams</a>, in the editor 5 times, both with and without the change, for a total of 10 runs. Profiling was done with <a href=\"https://superluminal.eu/\" rel=\"nofollow ugc noopener\">Superluminal</a>.</p>\n<figure><img src=\"https://larstofus.com/wp-content/uploads/2026/10/image-4.png?w=1024\" alt=\"\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>To put the following numbers into perspective, let me note that I will mostly talk about the overall CPU time, summed up over all threads, not just the time on the game thread. This is not done to artificially inflate the numbers, but to make the numbers more consistent and easier to compare. The actual effect on the editor start time is (very roughly) the measured time divided by the number of cores.</p>\n<p>In the vanilla version of the engine, a whopping 12.90 seconds were spent in FSHA1::Update. In the modified version using xxHash, this time shrunk to just 1.59 seconds spent in FXxHash64Builder::Update. That’s eight times faster! Mission accomplished.</p>\n<p>Normally, this article would now end with a link to a pull request so that anybody interested in the change could integrate it into their own version of the engine while we wait and hope that somebody at Epic would see the pull request and merge it into the main branch.<br />\nWell, this time I have even better news: The change already got accepted! (not merged however, this seems still to take a few days more)<br />\nI submitted the <a href=\"https://github.com/EpicGames/UnrealEngine/pull/15237\" rel=\"nofollow ugc noopener\">pull request</a> just a few days before writing this article and those few days were already enough for somebody at Epic to not only review my change but also polish it up. So let’s take a look some of the changes that were done to my proposed change:<br />\nOne very smart feat that I hadn’t thought of was to wrap the xxHash into another struct, FShaderHash. This doesn’t change the behavior right now but will make it easier to change the hash algorithm again in the future if an even faster one is needed without changing the code in many different places.<br />\nFixed a compile error for non-editor builds: That was an oversight on my sight. I had only tested my change in an editor build, mainly because my original profiling was also done in editor. I might need to add non-editor builds to my growing list of checks to do before a pull request in the future.<br />\nAnd that was it. If you enjoyed this article and want to read more about game optimization in the future, consider following me on <a href=\"https://bsky.app/profile/larstofus.bsky.social\" rel=\"nofollow ugc noopener\">BlueSky</a>, <a href=\"https://mastodon.gamedev.place/@LarsThiessen\" rel=\"nofollow ugc noopener\">Mastodon</a> or <a href=\"http://www.linkedin.com/in/larstofus\" rel=\"nofollow ugc noopener\">Linkedin</a> where I post all my articles. Or subscribe directly to my blog right below the article.</p>","headings":[]}}