Visual Studio 2022 Support!

Hello! We have very good news today. We just released Visual Assist 2021.5 and it has our official support for the Visual Studio 2022 release.

This blog could be as short as that sentence, but I’d like to write a bit more about our support and how we got here. Meanwhile I recommend if you’re using VS2022 you download and install 2021.5 now!


Historically it’s been very important to us to release support for new versions of Visual Studio very quickly, and if you’ve read our blog posts this year about VS2022, you’ll have read me say that before. While many customers stay on older versions for some time, we have a lot of people who upgrade immediately, so we’ve always put a lot of emphasis on being able to ship a version of Visual Assist supporting new versions of Visual Studio quickly. While I’ve been product manager here for almost three years, this is the first new major version of Visual Studio during that time, and I and the whole team were keen to continue that speedy-support tradition.

We started work supporting VS2022 early, and we’ve shared our progress over this past nine months about the work we’ve been doing to support VS2022, with beta support for Previews 3, skipping 4 due to a breaking bug, and 5, 6, and 7/RC. We released Visual Assist 2021.4 shortly before Visual Studio 2022 was released, and many of you are using it with VS2022 already.

Visual Studio 2022 was a large change from previous versions. Not only did it change to 64-bit, but there are many new APIs as well, and these APIs change the interaction model from synchronous to asynchronous interaction. This is a pattern Visual Studio has been following for several years (and we encourage it—it really helps the IDE) but as you may know migrating from any sync to async model is rarely trivial. Usually, the majority of the work for each new Visual Studio release is around adapting to API changes, and that was the case here too. In fact, the most major bug we saw using Visual Assist (abbreviated VAX) 2021.4 with VS2022 and which was one of the issues we fixed for today’s official support, an issue where the code suggestions window sometimes did not show in the right place, was related to the move to one specific async API.


  • We released Visual Assist 2021.4 on October 29.
  • Visual Studio 2022 was released on November 8, nine days later.
  • VAX 2021.4 overall worked pretty well with the final VS2022 build
    • But both we and some customers found a few more issues, and we’ve spent the past two weeks since VS’s release resolving them
  • VAX 2021.5 with official support for Visual Studio 2022 was released on Nov 22!

Official Support for VS2022

Yesterday afternoon US time we posted Visual Assist 2021.5 on our website. We have a rolling release mechanism and in about a week you should see in-IDE notifications about the new release, followed a couple of weeks later with the new version being available in the Visual Studio Marketplace. However you can directly download and install it now.

We’ve been working on VS2022 for something like nine months now and we’re really happy to have Visual Assist publicly available with Visual Studio 2022 support. We hope it is useful to you!

A note of thanks: VS2022 was a large change from previous versions, and Microsoft has been very open and helpful. We’re very grateful to them for their communications with us, the beta program, and their assistance while we’ve added support. Thank you!

I want to note as well that though as PM I get to write these posts, I really do very little, and all the credit for this release and VS2022 support goes to our amazing team. Thank you!

Visual Assist 2021.4 is released! (And notes on Visual Studio 2022)

We are pleased to have just released Visual Assist 2021.4. VAX uses a rolling release mechanism, so it will be a couple of weeks until VAX notifies you in-product and a couple more before it’s available on the Visual Studio store, but you can download Visual Assist 2021.4 today from our website.

VAX 2021.4 is a quality-focused release. Our last release, 2021.3, was mostly focused on supporting the upcoming Visual Studio 2022 Previews. That early work on support for VS2022 means that when the official release of VS2022 is out, we’ll be able to ship official support very fast. (More on this below.)

However, not everyone upgrades to a new Visual Studio release immediately — in fact many people have very good reasons for staying on older versions for quite some time! — and we want to focus on providing what all our customers across many versions need. (We still support VS 2005!) That’s the focus for this version. This release, as a quality release, focuses on fixing bugs and adding changes for everyone.

Our release notes contain full info, but some notable changes include support for the new External Include Directories property in Visual Studio, and updating the Code Inspection engine to LLVM/Clang version 12.0.1. There are a plethora of bug fixes as well. All up we feel this release is a solid update for you no matter which version of Visual Studio, and for all ways that you use Visual Assist.

Visual Studio 2022

Swiftly supporting new versions of Visual Studio is very important to us, because we understand it’s important to many of you, and we hope you’ve enjoyed seeing VAX working in many of the Visual Studio 2022 Previews. We expect VS2022 to be released very soon. In fact, as we were preparing this release, Previews 5, 6 and 7 came out, the pace increasing so fast that our installer only mentions support for Preview 6, but we do in fact support Preview 7 as well. At the same time we’ve seen significant stability improvements with each newer preview.

We don’t want to delay our release schedule to wait until VS2022 is shipped, especially because this release is focused on what customers using other versions need, which is why we’re releasing now. But since VS2022 will be released so soon, and since we are very ready for that to happen, you can expect a swift mini-update from us adding official support.

In other words:

  • VAX 2021.4 supports Visual Studio 2022 Previews 5 and 6 (with issues leading to hangs), and 7/RC3 (fully)
  • We’re eagerly waiting for VS2022 to be released, and we’ll add official support for it very quickly when it’s out
Visual Assist 2021.4 running in Visual Studio 2022 Preview 7 (Release Candidate 3)
Visual Assist 2021.4 running in Visual Studio 2022 Preview 7 (Release Candidate 3)

We recommend you install Visual Assist 2021.4 now, and we look forward to shipping official support for Visual Studio 2022 very soon.

Visual Assist support for Visual Studio 2022 Previews!

Visual Assist support for Visual Studio 2022 Previews!

There’s a lot of interest in the developer community about the new version of Visual Studio, which is in preview currently. This week we released Visual Assist 2021.3 (build 2420), and Visual Assist includes beta support for the Visual Studio 2022 Previews.

VAssistX menu open in the Visual Studio 2022 Extensions menu
Visual Assist 2021.3 running inside Visual Studio 2022 Preview 3

Visual Studio Preview

Visual Studio (VS) 2022’s main change—and it’s a significant one—is that it will become a 64-bit process. Since Visual Assist (VA or VAX) runs as a plugin, in-process, we needed to build a 64-bit version of our plugin DLL. Those who have upgraded 32-bit code to 64-bit code before know that, even in well-architected code, it takes some work even just to review code to ensure it is correct. In addition, the new version adds and modifies a number of APIs we rely on to interact with the IDE. Adapting to those was the most significant change for us.

We’ve tested fully against VS 2022 Preview 2, and in fact the installer says ‘Preview 2’. There are some known regressions:

  • VA Quick Info not appearing when triggered by keyboard in VS 2022 [case: 146063]
  • Source Links example plugin does not load in VS 2022 [case: 146012]
  • Changing from Cascadia to another font for italicized system symbols requires restart in VS 2022 [case: 145979]
  • plus a few others.

Visual Studio 2022 Preview 3 was released two days ago—overlapping timing with our release—and our regression tests are showing some failures. Currently we believe those are because of changed behaviour in a Visual Studio API which we use when verifying in-IDE behaviour (ie not an issue in VAX itself), but it is always possible that once that is resolved further test failures will need to be resolved. However, we believe the current build is well worth trying out on Preview 3 as well.


Many of our customers strain the Visual Studio IDE, with many plugins and SDKs installed. Both to help them, and because we believe it’s part of being a good member of the Visual Studio ecosystem where our plugin sits alongside others, last November we greatly reduced the in-process memory usage largely through (spoiler: the full blog is worth reading) use of memory-mapped files.

Now that Visual Studio 2022 is a 64-bit process, that work is not necessary for VS2022. For older versions of Visual Studio, those techniques are still used, so if you’re using VS 2019 or even VS 2005 with Visual Assist 2021.3, you’ll still benefit from the lighter memory impact within the IDE.

When we did that work, we also focused on performance to ensure that the changes to memory access had either zero or a positive impact. The blog notes that for heavy usage, we had equal performance; for small projects, VAX actually was a bit faster. Despite no longer needing the memory usage code we added, VS 2022 benefits from that performance work as well, plus some more work we’ve done while adding support. Since it’s a beta build, and Visual Studio itself is in preview, we do not have hard numbers. But a rough guideline is that an operation like Find References that previously may have taken (say) two minutes will now take about one minute twenty seconds, or about two thirds the time.


It’s historically been very important to us to have swift support for new versions of Visual Studio, and this work is our foundation for quickly officially supporting Visual Studio 2022 when it is officially released. While the main focus of this release was VS 2022 support, there are other changes as well in 2021.3, which we’ll document in the What’s New. We know we have many customers using older versions of Visual Studio, and as well as those improvements today you can look forward to further improvements focusing on other, non-VS areas as we switch back to a more normal focus in our next release.

We’re really happy to be able to ship beta support for the Visual Studio 2022 previews, and providing an even faster Visual Assist is a happy bonus. We’ll continue to work and look forward to shipping full support when Visual Studio publishes its final release.

Visual Assist 2021.3 is available for download on our website now, and will be on the Visual Studio Marketplace in a few days. Enjoy!

Unreal Engine ‘Quality Of Life’ in Visual Assist 2021.2

Unreal Engine ‘Quality Of Life’ in Visual Assist 2021.2

The first two releases of Visual Assist this year contain some great Unreal Engine quality-of-life improvements you may want to take advantage of.

While we’ve always announced features in our changelog and release blogs, we’re starting to blog in greater detail about some of what we change — our December blog about reducing memory usage started this — and this time we’ll dig a bit more into two changes improving using Unreal Engine with Visual Assist.

This applies only to versions 2021.1 and 2021.2, the first two versions this year. If you’re reading from the future, there’s likely much more for UE than is described here!

There are two notable items in these versions:

  • Improving parse times for Unreal Engine projects
  • Removing unwanted generated headers and symbols

These mean that your Unreal Engine projects should be fully usable with Visual Assist faster when you open them, and that Visual Assist only shows and uses methods and other symbols that you’re really interested in.

Parse Times

When a solution is opened in Visual Studio, Visual Assist (VAX) parses that solution. This generates the databases of symbols and other data which VAX uses to be able to implement features like GoTo Related, extra syntax highlighting, parameter info, and so forth.

Parsing can take time. Although VAX is not based around a C++ compiler (one of its strengths), parsing is analogous to compiling a project, and while you can use VAX right away, some features require that data before they will work. Unreal Engine solutions can be very large. Therefore, we spend a lot of thought on how to speed up parse time to make the time between opening a solution and having VAX fully functional be as short as possible.

Avoiding Unnecessary Parsing

This following is going to sound ridiculously simple, and it is. What’s the best way to spend less time doing something? Not to do it.

We do focus on optimisations; the parse engine is heavily multi-threaded; the database uses considerably less memory than it used to; and other techniques. But ultimately, the best way to reduce parse time is to do less parsing.

Unreal Engine projects include plugins. These are additional libraries that add features to your game or project (in-editor or at runtime.) The UE editor lets you enable and disable these, so it’s common to have several installed but only use a subset of them. Yet, the presence of plugins is a key item that makes parsing a UE project lengthier. We added an option to turn off parsing them.

In 2021.1 we added an option to disable indexing these plugins. When off, the default, UE plugins were not parsed.

However, we realised this was based on a flawed understanding: that if plugins are third-party (as plugins often are) then you may not need them to be parsed into VAX’s memory: after all, we thought, you’re unlikely to do a ‘find references’ on an internal method of a third-party library. Omitting them from being parsed would not affect day to day use of Visual Assist. But we got feedback that it was more common than we thought for plugins to be first-party: that is, for UE developers to move parts of their game or project’s functionality into a plugin. That means that it was necessary to parse some plugins, and so a simple on/off parse all-or-none toggle was not useful.

In 2021.2 we expanded the setting so that Visual Assist can parse plugins that are genuinely used by your project, only. Today the ‘Index Unreal Engine plugins’ setting has three options for parsing plugins:

  • None: don’t parse anything in the Plugins folder. This reduces parse time the most
  • Referenced: parse only plugins references by the project, and referenced by default. Depending on how many plugins you have installed that are not used, this still reduces parse time. It is the recommended setting
  • All: parse all plugins; there is no reduction in parse time.
Visual Assist Options dialog, showing the settings to index all, referenced, or no Unreal Engine plugins

Real-World Performance Improvements

The amount of time saved by not parsing unused plugins depends on the complexity of your Unreal Engine solution and the specific machine on which Visual Studio runs, but some real-world measurements are as follows:

Time (minutes and seconds) to fully index an Unreal Engine project, when indexing UE plugins. The percentage annotations are the fraction the Referenced Plugins or No Plugins times are of the time indexing the same project with all plugins.

The absolute values may vary but we expect the relative percentage to be broadly applicable.


If you open a file from a plugin folder which was not parsed (either not referenced, or the above setting was set to None), then you will see a notification message that the file was not parsed and Visual Assist won’t provide your expected functionality for that file. This is shown only once, and won’t be shown again until Visual Studio restarts.

Avoiding Parsing UE-Generated Files

Saving a very useful change for last — there are many places Visual Assist shows you the symbols and files it’s aware of. The two main windows are Open File In Solution which lists all headers (and other files), and Find Symbol will list every symbol in the database. Unreal Engine, however, generates header files, and these include generated symbols, neither of which are useful in practice when coding on your UE project in Visual Studio.

Voila, a new setting, which means Visual Assist won’t show *.generated.h files, and the Find Symbol dialog is not polluted with generated symbols either. The setting is called ‘Index generated code’ and is off by default. That is, the default is aimed at clean results within Visual Assist, to not index these generated files and store those generated symbols. You can always turn it back on if you want the old behaviour.

Visual Assist Options dialog showing the checkbox to index generated code. By default it is off, which means the results shown within Unreal Engine will be cleaner

Unreal Engine with Visual Assist 2021.1 and 2021.2

The above covers only the first two releases this year, and we have more planned. However, the parsing speed improvements (including our followup for more granular parsing of plugins) and removing generated files and symbols by default should the general ‘quality of life’ using Visual Assist with Unreal Engine. As always, feedback is welcome!

Technical Deep Dive: Reducing Memory Consumption in Visual Assist build 2393

Technical Deep Dive: Reducing Memory Consumption in Visual Assist build 2393

November 2020’s release of Visual Assist had some significant memory usage improvements, great for those with large projects. Here’s how we did it.

Written by David Millington (Product Manager), Goran Mitrovic (Senior Software Engineer) and Christopher Gardner (Engineering Lead)

Visual Assist is an extension which lives inside Visual Studio, and Visual Studio is a 32-bit process, meaning that its address space, even on a modern 64-bit version of Windows, is limited to a maximum of 4GB. Today 4GB doesn’t always go very far. A typical game developer, for example, may have a large solution, plus perhaps the Xbox and Playstation SDKs, plus other tools – already using a lot of memory – plus Visual Assist. A lot of Visual Assist is built around analysis of your solution, and that requires storing data about your source code, what we call the symbol database. Sometimes, with all of these things squashed into one process’ memory space together, some users with large and complex projects start running out of memory.

The latest version of Visual Assist (build 2393, 28 Oct 2020) reduces in-process memory consumption significantly. It’s a change we think will help many of you who are reading this, because those with large solutions who run into memory issues should find those memory issues alleviated or disappearing completely; and those with small or medium solutions may find Visual Assist runs a little faster.

Plus, it’s just part of being a good member of the Visual Studio ecosystem: as an extension relied on by thousands of developers, yet sitting in the same shared process as other tools, we should have as little impact as we can.

Chart showing memory usage from a Find References operation in the Unreal Engine source code. The new build of Visual Assist uses 50% the memory of the previous build (152 MB vs 302 MB)
Difference in memory usage running a Find References on the Unreal Engine 4.26 source code. Smaller is better.

The chart above shows that the new build of Visual Assist reduces VA’s memory usage by about 50% – that is, half as much memory is used. You can see more charts below, and we consistently see 30%, 40% and 50% memory savings.

We’d like to share some technical information about the approaches we took to achieve this, and we hope that as C++ or Windows developers you’ll find the work interesting. This is a fairly long blog, and starts off light and gets more technical as it goes on. It covers:


Many readers may know this, but to follow this post here’s a quick primer on some concepts. Feel free to skip to the next section if you’re already familiar.

Address space refers to the total amount of memory an application can use. It’s usually limited by the size of a pointer (because a pointer points to memory): a 32-bit pointer can address 232 (about 4 billion) bytes, which is 4GB. So we say that a 32-bit process has a 32-bit address space, or an address space of 4GB. (This is hand-wavy – although true, on 32-bit versions of Windows this 4GB was split between kernel and user mode, and a normal app can only access usermode memory; depending on settings, this actually meant your app could access only 2GB or 3GB of memory before it could not allocate any more. On a 64-bit version of Windows, a 32-bit app has the entire 4GB available. Plus, there are techniques to access more memory than this even on 32-bit systems, which is getting ahead of where this blog post is going.)

This address space is a virtual address space; the application uses virtual memory. This means that the 4GB is not actually a sequential block of memory in RAM. Pieces of it can be stored anywhere, including on disk (swapped out) and loaded in when needed. The operating system looks after mapping the logical address, the address your application uses, to the actual location in RAM. This is important because it means that any address you use has what backs it, where it actually points to, under Window’s control.

A process is how your application is represented by the operating system: it is what has the virtual address space above, and contains one or more threads which are the code that runs. It is isolated from other processes, both in permissions and memory addresses: that is, two processes do not share the same memory address space.

If you’re really familiar with those concepts, we hope you’ll forgive us for such a short introduction. OS architecture including processes, threads, virtual memory etc is a fascinating topic.

Background – Where Visual Assist Uses Memory

Visual Assist parses your solution and creates what we call the ‘symbol database’, which is what’s used for almost every operation – find references, refactoring, our syntax highlighting (which understands where symbols are introduced), generating code, etc. The database is very string-heavy. It stores the names of all your symbols: classes, variables and so forth. While relationships between symbols can be stored with relatively little memory, strings themselves take up a lot of space in memory.

Our first work on memory optimization focused on the relationships, the links between data, and metadata stored for each symbol, and we did indeed reduce the memory they used. But that left a large amount of memory used by strings generated from source code. In addition our string allocation patterns meant strings were not removed from memory when memory became full and there was allocation pressure, but instead at predefined points in code, and that also increased the risk for large projects of getting out of memory errors.

Clearly we needed to solve string memory usage.

We researched and prototyped several different solutions.

String Storage Optimizations

Stepping back in time a little, string memory usage is obviously not a new problem. Over time, Visual Assist has used several techniques to handle string storage. While there are many possible approaches, here’s an overview of three, one of which Visual Assist used and two of which it has never used, presented in case they are new or interesting to you.

String interning addresses when there are many copies of the same string in memory. For example, while Visual Assist has no need to store the word “class”, you can imagine that in C++ code “class” is repeated many times throughout any solution. Instead of storing it many times, store it once, usually looked up by a hash, and each place that refers to the string has a reference to the same single copy. (The model is to give a string to the interning code, and get back a reference to a string.) Visual Assist used to use string interning, but no longer: reference counting was an overhead, and today the amount of memory is not an issue itself, only the amount of memory used inside the Visual Studio process.

While we’re discussing strings, here are two other techniques that are not useful for us but may be useful for you:

  • To compress strings. Visual Assist never used this technique: decompression takes CPU cycles, and strings are used a lot so this would occur often.
  • To make use of common substrings in other strings: when a string contains another string, you can refer to that substring to save memory. A first cut might use substrings or string views. This is not useful for us due to the overhead of searching for substrings, which would be a significant slowdown, and the nature of the strings Visual Assist processes not leading to enough duplication of substrings to make it worthwhile. A more realistic option (in terms of performance, such as insertion) for sharing string data than shared substrings would be to share data via prefix, such as storing strings in tries. However, due to the nature of the strings in C++ codebases, our analysis shows this is not a valuable approach for us.

The approach we took to the recent work was not to focus on further optimising string storage, but to move where the string storage was located completely.

Moving Out Of Process: Entire Parser

Visual Assist is loaded into Visual Studio as a DLL. The obvious approach to reducing memory pressure in a 32-bit process is to move the memory – and whatever uses it – out of process, which is a phrase used to mean splitting your app up into multiple separate processes. Multi-process architectures are fairly common today. Browsers use multiple processes for security. Visual Studio Code hosts extensions in a helper process, or provides code completion through a separate process.

As noted in the primer above, a second process has its own address space, so if we split Visual Assist into two, even if the second was still a 32-bit process it could double the memory available to both in total. (Actually, more than double: the Visual Studio process where Visual Assist lives has memory used by many things; the second process would be 100% Visual Assist only. Also, once out of Visual Studio, we could make that second process 64-bit, ie it could use almost as much memory as it wanted.) Multi-process architectures can’t share memory directly (again hand-wavy, there are ways to read or write another process’s memory, or ways to share memory, but that’s too much for this blog); generally in a multi-process architecture the processes communicate via inter-process communication (IPC), such as sockets or named pipes, which form a channel where data is sent and received.

There were two ways to do this. The first is to move most of the Visual Assist logic out to a second process, with just a thin layer living inside Visual Studio. The second is just to move the memory-intensive areas. While the first is of interest, Visual Assist has very tight integration with Visual Studio – things like drawing in the editor, for example. It’s not trivial to split this and keep good performance. We focused instead on having only the parser or database in the second process.

Prototyping the parser and database in a second process, communicating with IPC back to the Visual Studio process, showed two problems:

  • Very large code changes, since symbols are accessed in many places
  • Performance problems. Serializing or marshalling data had an impact. Every release, we want VA to be at least the same speed, but preferably faster; any solution with a performance impact was not a solution at all

Moving Just Memory

Multi-process is not a required technique, just one approach. The goal is simply to reduce the memory usage in the Visual Studio process and move the memory elsewhere; we don’t have to do that by moving the memory to another process—and this is a key insight. While multiprocess is a fashionable technique today, it’s not the only one for the goal. Windows provides other tools, and the one we landed on is a memory mapped file.

In the primer above, we noted that virtual memory maps an address to another location. Memory-mapped files are a way to map a portion of your address space to something else – despite the name, and that it’s backed by a file, it may not be located on disk. The operating system can actually store that data in memory or a pagefile. That data or file can be any size; the only thing restricted is your view of it: because of the 32-bit size of your address space, if the mapped file is very large you can only see a portion of it at once. That is, a memory mapped file is a technique for making a portion of your address space be a view onto a larger set of data than can fit in your address space, and you can move that view or views so, although doing so piece by piece, ultimately a 32-bit process can read and write more data than fits in a 32-bit address space.

Benchmarking showed memory mapped files were significantly faster than an approach using any form of IPC.

The release notes for this build of Visual Assist referred to moving memory ‘out of process’. Normally that means to a second process. Here, we use the term to refer to accessing memory through a file mapping, that is, accessing memory stored by the OS, and potentially more memory than can fit in the process’ address space. Referring to it as out of process is in some ways a holdover from when the work was planned, because we had initially thought we would need multiple processes. But it’s an accurate term: after all, the memory is not in our process in a normal alloc/free sense; it’s an OS-managed (therefore out of process) resource into which our process has a view.

Note re ‘memory mapped files were significantly faster than … using any form of IPC’: sharing memory mapped files can be a form of IPC as well – you can create the mapped file in one process, open in another, and share data. However, we had no need to move logic to another process – just memory.

Chunk / Block Structure and Allocation / Freeing

We already mentioned that the data we stored in the memory mapped file is strings only. In-process, we have a database with metadata fields; in the mapped view are all strings. As you can imagine any tool that processes source code uses strings heavily; therefore, there are many areas in that mapped memory we want to access at or near-at once.

Our implementation uses many file mappings to read and write many areas at once. To reduce the number, each is a fixed size of 2MB. Every one of these 2MB chunks is a fixed heap, with blocks of a fixed size. These are stored in lists:

  • 2MB chunks that are mapped, and locked as they are being used to read or write data
  • Chunks that are mapped, but unused at the moment (this works like a most recently used cache, and saves the overhead of re-mapping)
  • Chunks that are not mapped
  • Chunks that are empty

Most C++ symbols fit within 256 bytes (note, of course, this is not always the case – something like Boost is famous for causing very long symbol names.) This means most chunks are subdivided into blocks 256 bytes long. To allocate or free is to mark one of these blocks as used or unused, which can be done by setting a single bit. Therefore, per two-megabyte chunk, one kilobyte of memory is enough to represent one bit per block and to allocate or deallocate blocks within a chunk. To find a free block, we can scan 32bits at a time in a single instruction, BitScanForward, which is handily an intrinsic in Visual C++.

This means that Visual Assist’s database now always has a 40MB impact on the Visual Studio memory space—twenty 2MB chunks are always mapped—plus a variable amount of memory often due to intermediate work, such as finding references, which can be seen in the charts below and which even in our most extreme stress test topped out at a couple of hundred megabytes. We think this is very low impact given the whole 4GB memory space, and given Visual Assist’s functionality.


There are a number of optimizations we introduced this release, including improvements for speedily parsing and resolving the type of type deduction / ‘auto’ variables, changes in symbol lookup, optimisations around template handling, and others – some of which we can’t discuss. I’d love to write about these but they verge into territory we keep confidential about how our technology works. We can say that things like deducing types, or template specialisation, are faster.

However we can mention some optimizations that aren’t specific to our approach.

The best fast string access code is code that never accesses strings at all. We hash strings and use that for string comparison (this is not new, but something Visual Assist has done for a long time.) Often it is not necessary to access a string in memory.

Interestingly, we find in very large codebases with many symbols (millions) that hash collisions are a significant problem. This is surprising because hash algorithms usually are good at avoiding collisions, and the reason is that we use an older algorithm, and one with a hash value only 32 bits wide. We plan to change algorithms in future.

We also have a number of other optimizations: for example, a very common operation is to look up the ancestor classes of a class, often resolving symbols on the way, and we have a cache for the results of these lookups. Similarly, we reviewed all database lookups for areas where we can detect ahead of time a lookup does not need to be done.

Our code is heavily multi-threaded, and needs to be performant, avoid deadlocks, and avoid contention. Code is carefully locked for minimal locking, both in time (duration) and scope (to prevent locking a resource that is not required to be locked, ie, fine-grained locking.) This has to be done very carefully to avoid deadlocks and we spent significant time analysing the codebase and architecture.

In contrast we also reduced our use of threads. In the past we would often create a new thread to handle a request, such as to look up symbol information. Creating a thread has a lot of overhead. Now, we much more aggressively re-use threads and often use Visual C++’s parallel invocation and thread pool (the concurrency runtime); the performance of blocking an information request until a thread is available to process it is usually less than creating a thread to process it.

Symbols are protected by custom read-write locks, which is written entirely in userspace to avoid the overhead of kernel locking primitives. This lock is custom written by us, and is based around a semaphore which we find provides good performance.


All these changes were done with careful profiling and measurement at each stage, testing with several C++ projects. These included projects with 2 million symbols, 3 million symbols, and 6 million symbols.

The end result is the following:

  • For very large projects – we’re talking games, operating systems, etc – you will see:
    • 50% less memory usage between low/high peaks doing operations such as Find References (average memory usage difference is less once the operation is complete; this is measured during the work and so during memory access.)
    • Identical performance to earlier versions of Visual Assist
  • For smaller projects:
    • Memory usage is reduced, though for a smaller project the effect is not so noticeable or important. But:
    • Improved performance compared to earlier versions of Visual Assist

In other words, something for everyone: you either get far less memory pressure in Visual Studio, with the same performance, or if memory was not an issue for you then you get even faster Visual Assist results.

Here are the results we see. We’re measuring the memory usage in megabytes after the initial parse of a project, and then after doing work with that project’s data—here, doing a Find References, which is a good test of symbol database work. Memory usage here is ascribed to Visual Assist; the total memory usage in the Visual Studio process is often higher (for example, Visual Studio might use 2GB of memory with a project loaded between itself and every other extension, but we focus here on the memory used by Visual Assist’s database and processing.)

One good test project is Unreal Engine:

Chart showing memory usage in an Unreal Engine project, with 28% less memory used after the initial parse, and 50% less after a Find References
Memory savings for Unreal Engine 4.26 (smaller is better):
Initial parse (180MB, vs 130MB now) and
Find References (302MB vs 152MB now)

Another excellent large C++ codebase is Qt:

Chart showing memory usage for Qt, with 40% less memory used after the initial parse, and also 40% less after a Find References
Memory savings for Qt (smaller is better):
Initial parse (424MB, vs 254MB now) and
Find References (481MB vs 291MB now)

Our feedback has been very positive: we often work with customers with very large codebases and significant memory usage from many sources inside Visual C++, and the lower impact of Visual Assist has made a noticeable difference. That’s our goal: be useful, and be low-impact.

We hope you’ve enjoyed reading this deep dive into the changes we made in Visual Assist build 2393. Our audience is you – developers – and we hope you’ve been interested to get some insight into the internals of a tool you use. While as the product manager I get to have my name on the post, it’s not fair because I did nothing: the credit goes to the engineers who build Visual Assist, especially Goran Mitrovic and Sean Echevarria who were engineers developing this work, and Chris Gardner our team lead, all of whom helped write this blog post.

A build of VA with the changes described in this post is available for download now, including trying it for free if you’d like. If you’re new to VA, read the quick start or browse our feature list: our aim is not to have the longest feature list but instead to provide everything you need, and nothing you don’t. We also do so with minimal UI – VA sits very much in the background. Our aim is to interrupt or distract you as little as possible while being there when you need it. You can see the kind of engineering we put into VA. It’s built by developers for developers.

License and Website Changes for Visual Assist

You’ve spoken, and we’ve listened! Our recent website and license migration failed to deliver the high quality experience you deserve.

Recently, Whole Tomato migrated our website to a new backend technology and a much needed new license technology for Visual Assist. There have been some hiccups, and some of the changes to licensing resulted in delays sending licenses to customers, and concerns expressed to us. We’ve heard you. In this post we’d like to cover what changed and why for both the website and licenses, as well as what steps we are taking to address concerns.

Whole Tomato Website

We migrated the main Whole Tomato website,, to the same backend used by other Idera websites. This retained all existing content and ensured our web team only needs to maintain one server stack.

During this content migration, there were a few changes. The most significant is that when you download a trial or a new build, you are asked for information about yourself: name, email, address, and so forth. For a trial, we believe this is ok – it is standard business practice to know who is trying out our software and allows us to  follow up in the future. You can opt out of all marketing communications from Whole Tomato here. Your confirmation email also includes instructions for opting out, plus our privacy policy also has a link (section 14, Unsubscribe.)

However, there is no reason to ask for licensed customers’ information again when downloading a new build of Visual Assist for which you are already validly licensed. This has been pointed out to us, sometimes quite vocally, both through support and online. We hear you. The website no longer requires customers to enter personal information to download new builds.

The new website should also be more stable and faster.

License Technology

At the same time, we also changed the technology used to generate and validate license serial numbers for Visual Assist. Once again, this is to ensure a single technology is used across multiple products. It’s also a benefit for you because this licensing technology reduces uncertainty about licensed usage and decreases over deployment compliance issues, which is something that many large customers request. No one wants to be in a situation where audits are necessary – you don’t, and we don’t.

It’s a great goal, but customers have reported two issues: delays in generating new serial numbers after purchase and concerns about individual registration data, even for large volume serial numbers.

Let’s look at the current license options available, and changes we plan to introduce in the future.

Current License Options

When you purchase a Visual Assist license, you have the following options:

  • As an individual:
    • You purchase and get a serial number. You need a user account (see below) on our website, and your serial number is registered against that account. You can use this serial number on multiple VMs, so long as the serial number is used only by the same person.
  • As a company:
    • You purchase and get a serial number, one per developer. Just as for individuals above, each serial number must be registered against a developer’s EDN account. Each developer can use it on multiple VMs.
    • You purchase a multi-user serial number. This is a single number that is valid for multiple people. Just as for normal serials, when any individual developer installs and registers Visual Assist, they will need their own user account. Each developer can use it on multiple VMs.

There are also some temporary options that you may have seen if you encountered issues: a manually generated legacy serial number using the old license system, and an eSlip file, which is a single license file shared for a team but requiring an internet connection. We’ve used these for limited cases when none of the above licenses work for a team due to technical reasons.

The licensing changes are new to us too, and we may not have clearly explained them when you purchased or contacted Support.

User Accounts

What is a user account? User accounts provide a single licensing account across all Idera-owned products. Create yours here, and then use those login credentials when registering your license.

Registering Visual Assist. Enter your serial number at the top, and use the email and password for your Idera user account below
Registering Visual Assist. Enter your serial number at the top, and use the email and password for your Idera user account below

Right now, the webpage is not ideal, and we’ve had some feedback about that too. More on what will change there below.

Licenses In The Future

The majority of issues we’ve seen have been to do with a missing use case: a team with multiple developers who either wish to not register individually or need to use the license in a disconnected environment. We believe it’s reasonable for personal or individual users to register via an account, but we understand it’s a barrier for some larger teams.

Within the next week, we are adding a new license option to address this scenario. If you are a large company with many developers, or you operate disconnected from the net, you will be able to purchase a network named user license. This is a single license shared by the whole team. Individuals can use it on multiple VMs. No internet connection is required: instead, you run a license server on your internal network, which manages all verification without contacting us.

You’ll be given this license option if you purchase Visual Assist for a team of five or more, or by request to our sales / licensing team.

Running a license server may not be ideal for some teams with strict IT requirements. If your team is unable to use this option, you can always contact our sales or license teams to discuss some other options we can make available.

This retires eSlip licenses (except through licensing support requests) and legacy serial numbers, leaving three license options:

  1. Personal use, or multiple individual developers: individual serial numbers, registered for each developer through your user account.
  2. Multiple individual developers in a small team: a multi-user serial number, registered for each developer through your user account.
  3. Multiple individual developers in a large team, or by request for small teams: a network named user license, with no registration or internet access required.

We also expect the speed of license generation to be faster at the same time we introduce this new option. Note our staff don’t work weekends, so if you order on a Friday, you may not get your serial number until Monday. Orders during the week should be next-day or sooner, and we aim to process each one within a few hours.

License support requests are also now handled by a dedicated team with experience with this license technology. That means they are familiar with the issues you may encounter and should be able to speedily resolve them. They have a dedicated email address: (You can email this directly. If you contact normal support, your email will also be forwarded to and handled by the dedicated license team.)

In addition, we are replacing the user account website, with a planned launch date in early July. This is a brand new version of the user account website, built in Ext JS, where you will be able to create an account and view all your registered products and serial numbers. It will be quite minimal, clean, fast, and should be a lot clearer to use than the current website.

Preview of the new user account website - not yet launched! - showing products, serials, subscription status, and a separate pane for quick downloads
Preview of the new user account website – not yet launched! – showing products, serials, subscription status, and a separate pane for quick downloads


In short:

  • We rolled out a new website and new license system, and neither was quite perfect
  • You will not need to enter personal information to download your licensed software
  • The license system and where and how to use your account may not have been well explained, and we hope the above makes it clearer
  • We’re introducing a new license option, Network Named User License, that works better for large teams and teams who work offline
  • If you have issues or requests, we now have a dedicated license support team: please email
  • Our new user account website will have a clean UI and provide an easy site to view your products and licenses

Idera is a developer-focused company. We do listen, and we make changes if needed. We hope the above is easy to understand and use, and the changes we’re making solve your concerns.