views:

463

answers:

3

I am creating an extension for Visual Studio 2008, and because I didn't want to write my own parser for C++ (I'm not masochistic) I am using VCCodeModel.

Getting a simple field from these COM objects takes orders of magnitude more time than any of the other operations I am doing, and since I am drilling down to the method level of very large C++ projects I have this inefficiency at the lowest levels of my recursion.

   vcCodeBaseFunctions = ((Microsoft.VisualStudio.VCCodeModel.VCCodeElements)
              (vcCM.Functions));
   int i = 0;
   for (i = 1; i <= vcCodeBaseFunctions.Count; i++)
   {
     if (vcCodeBaseFunctions.Item(i).Kind == vsCMElement.vsCMElementFunction)
          parent.AppendChild(MethodWrapper.VCCodeFunctionToXML(
                          (VCCodeFunction)vcCodeBaseFunctions.Item(i)));
   }

The preceding code would iterate through all of the functions at the base level of a project, convert them to XML and then save them. The XML method would call multiple fields inside the VCCodeFunction like name, parameters, etc.

Is managed C++ faster than C# for this purpose? I have an inadequate understanding of how the back end of managed C++ is different than C#, but my intuition would lead me to believe that there is less of a "context switch" cost between managed and unmanaged code in C++, but am I wrong? I am getting a good bit of slowdown from what I believe is switching repeatedly between managed and unmanaged code in C++ using CodeModel, so am I correct in assuming that managed C++ would be faster?

A: 

The add-in/package language speed is nothing compared to the speed of the code model. Edit: ok, maybe I went overboard, but seriously, the first sentence here is correct.

280Z28
I'm not saying that codemodel isn't fast. What I am saying is that accessing fields from COM codemodel objects is taking almost all of the processor time (I've profiled this addon in ANTS). I am currently using C# and am wondering if managed C++ would be any faster.
A: 

C++ would be unlikely to be faster.

Writing your own parser might execute faster. Writing your own parser might take considerably longer, of course.

Will
Aren't you able to more easily reference unmanaged code from managed C++? Is the "context switching" between the .NET framework and the unmanaged code any different under C++ or is this just a syntactic sugar difference?
+1  A: 

There is an overhead with the COM interop layer in .NET. If you were to use C++, you could move your COM access into native code, which would speed up that section of the code access.

However, you're still going to have native->managed interop at some point, if you're planning to use C++/CLI. Somewhere in the chain, you'll be marshalling data across, although you may be a bit faster if you can move this outside of these loops (if you make your recursion 100% native, you'd have far fewer interop calls).

That being said, the VCCodeModel is not particularly fast - Although I agree that your getting some overhead with the COM interop, be aware that the profiler you're using may be exaggerating this. This is particularly true if you're using a tracing profiler, as you're going to be spending more time in those calls during profiling than during an actual release run. Profilers aren't perfect, and this may be a case where you're getting skewed results due to your profiler.

I suspect that your potential speed gains would not merit a port - although it would be difficult to know for sure without more information.

Reed Copsey
Can you be more specific in how a "tracing profiler" would be skewing the profiling results?Do you believe it would make any difference if I told you I was making around a dozen calls to COM object data members in the lowest level of recursion? Every method of large C++ projects having all of the relevant fields being extracted? This seems like a case where the COM interop is getting in the way, but I'm not sure.
Read up on tracing vs sampling profilers for details on how all profilers skew results. The biggest problem is that they have to completely disable optimizations and inlining by the JIT, and every method call slows things down. For you, going to native C++ would definitely be faster-but it's a question of how much faster. I'd expect that you'll see a very minor gain, so it all depends on how criticaly you need the speed gain. Optimization is almost always a balance of work/needs vs gains-how bad is the current situation, how much can you really improve it, and how much effort is involved?
Reed Copsey
Yep, that makes sense. You answered my question, but it wasn't the "I can garuntee that codemodel is 10x in native C++!" I was hoping for.
Yeah - sorry. Unfortunately, a lot will depend on what you're doing with the code model, how you're calling it, etc. Calls across the COM interop layer are more expensive than managed->managed or native->native calls - there is a cost. It's just not necessarily a huge cost.
Reed Copsey
I think I am still going to try out the C++ version of this, because lots of COM interop is happening at the lowest level of recursion for every method in a large C++ project I am browsing with VCCodeModel. I'm probably just going to make a C++ dll to handle the method processing and then call that from C#. The browsing of the codemodel would still have COM interop issues but that is insignificant compared to the time spent processing methods. Thanks again for your help though.
You'll probably get an improvement. The less you can pass between C# and the C++ side (ie: the "higher" you can make the managed -> native boundaries), the better the improvement. Let us know how it goes - I'm curious ;)
Reed Copsey