Frame rate counters in WP7
1. Render Thread FPS![]()
The number of frames per second that the independent simple animations and rendering thread is using. Keeping around 60 will provide a great experience, while a number of 30 fps will begin to show a poor experience to the end user.
2. User Interface Thread FPS
The number of fps that the primary user interface thread is experiencing. Property change notifications, data binding, primary managed code execution, and animations not handled on the render thread use this threads resources.
3. Textual Memory Usage
A specialized memory counter indicating the video memory used for storing application textures.
4. Surface Counter
A counter of the number of surfaces that are passed to the graphics chip
5. Intermediate Texture Count
The number of intermediate textures created for compositing.
6.Screen Fill Rate
A metric representing the number of complete phone screens being painted each and every frame.
| Counter | Ideal Minimum | Best Experience | Theoretical Max |
| Render Thread | 30 fps | 60 fps | 120 fps |
| UI Thread | 15 fps | > 15 fps | 120 fps |
| Screen Fill Rate | <= 2.0 | N/A |
Relative paths and Windows Services
So you have converted your console app to a Windows Service but now all your relative paths is relative to C:\Windows\system32 (or c:\Windows\SysWOW64)
.
This is because your service is executed by svchost.exe that is located in C:\Windows\system32 (or svchost.exe located in c:\Windows\SysWOW64 if you run a 32bit service on a 64bit Windows) and therefore has it as executing directory.
To resolve this I usually use the ResolvePath method bellow:
public static string ResolvePath(string path) { if (!Path.IsPathRooted(path)) { var executingAsmPath = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path; var directoryName = Path.GetDirectoryName(Uri.UnescapeDataString(executingAsmPath)); path = Path.Combine(directoryName, path); } return path; }
either resolving the path directly:
string logPath = ResolvePath(@".\log.txt");
or changing the current directory:
Directory.SetCurrentDirectory(ResolvePath(""));
Dynamic dispatcher (compiler view)
So in an earlier blog post I showed dynamic dispatching using the dynamic runtime in .NET4, in the example the stream gets passed to the correct ReadStream method depending on it’s runtime type.
class Reader { public void Read(Stream stream) { dynamic s = stream; ReadStream(s); } private void ReadStream(FileStream stream) { // ... } private void ReadStream(MemoryStream stream) { // ... } }
Lets dig a little deeper and look at what the C# compiler outputs, and get a feel for what the cost of using dynamic dispatching is.
[CompilerGenerated] private static class SiteContainer { public static CallSite<Action<CallSite, Reader, object>> Site; } public void Read(Stream stream) { if (SiteContainer.Site == null) { var argumentInfos = new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }; var binder = Binder.InvokeMember( CSharpBinderFlags.InvokeSimpleName | CSharpBinderFlags.ResultDiscarded, "ReadStream", null, typeof (Reader), argumentInfos); SiteContainer.Site = CallSite<Action<CallSite, Reader, object>>.Create(binder); } SiteContainer.Site.Target(SiteContainer.Site, this, stream); }
The above code is what the compiler replaces the Read method with.
The first time Read is called a dynamic call site binder to our ReadStream methods is created, this call site is then cached in the static SiteContainer so the hit of the call site create is only taken once. Target delegate is then invoked which dispatches the call to the correct ReadStream method.
The Target delegate is probably generated with a expression tree (probably why System.Runtime.CompilerServices.CallSiteOps exists to give access to internal CallSite<> members and why the call site is a parameter to the delegate) which would mean that the Target delegate is compiled once.
I highlighted all parts in the Read method that have something to do with the stream parameter in yellow.
To be able to do the dynamic dispatching the CSharpArgumentInfo for stream is flagged with CSharpArgumentInfoFlags.None resulting in that the type information will be looked up at runtime. This in contrast to the Reader class instance (highlighted in green) that is flagged as UseCompileTimeType that is always known at compile time.
As you probably concluded there is a fairly high initial cost of setting up a call site and generating delegates, this is on the other hand only done once and then cached.
Dynamic dispatch
In the example bellow we want the correct ReadStream method to be called when we pass it a stream. This example does not compile because the compiler doesn’t have enough type information at compile time to decide what method to run.
class Reader { public void Read(Stream stream) { ReadStream(stream); } private void ReadStream(MemoryStream stream) { // ... } private void ReadStream(FileStream stream) { // ... } }
To resolve the lookup error we have to manually add the runtime type checks, and a appropriate cast
to the correct type.
public void Read(Stream stream) { if (stream is MemoryStream) { ReadStream((MemoryStream)stream); } else if (stream is FileStream) { ReadStream((FileStream)stream); } }
In .NET4 the dynamic runtime was introduces and with it some nifty runtime features. One of these features
is dynamic dispatching that tells the compiler don’t worry about the type the dynamic runtime will invoke the correct method at runtime. For our example the code would look like this:
public void Read(Stream stream)
{
dynamic s = stream;
ReadStream(s);
}
So what will happen when we pass e.g. a BufferedStream to our method? You will get a
RuntimeBindingException from the dynamic runtime telling you the best overloaded method had some invalid argument. This best match error is a bit misleading because when no match is found it will take the first method in the list of declared method and return that as the best match, so it doesn’t have any significance.
A place where I found the best use for dynamic dispatching is when matching AST (Abstract Syntax Tree) nodes in a visitor. Instead of having a switch statement containing up to a 100 or more cases that also needs to be kept in sync with the rest of the implementation I have two lines of code.
IndexOf is culture sensitive
When you work with Unicode text a simple task as replacing double spaces with single space can be complex. The example bellow replaces double spaces while we find some:
static string ReplaceDoubleSpace(string text) { while (text.IndexOf(" ") != -1) { text = text.Replace(" ", " "); } return text; }
So in a passing test scenario:
[Test] public void ReplaceDoubleSpace_doubleSpaces_ReturnsRemovedDoubleSpaces() { string result = ReplaceDoubleSpace("Hello World"); Assert.That("Hello World" == result); }
But when we introduce a Unicode zero width non-joiner character ‘\u200c’
[Test] public void ReplaceDoubleSpace_unicodeNonJoinerCharacter_ReturnsTheSameString() { string result = ReplaceDoubleSpace("Hello \u200c World"); Assert.That("Hello \u200c World" == result); }
our implementation gets stuck in a death loop.
So this happens because the IndexOf has different behavior than the Replace method. The IndexOf method is in fact culture sensitive and is using the Unicode character table for matching where the zero width non-joiner character is included, while Replace uses the original matching method.
So if you want IndexOf to behave as Replace you should specify thatStringComparison.Ordinal should be used:
static string ReplaceDoubleSpace(string text) { while (text.IndexOf(" ", 0, StringComparison.Ordinal) != -1) { text = text.Replace(" ", " "); } return text; }
New Chrome profile image
New tab page in Chrome
Google added a new look for the “New Tab page” in the latest Chrome DEV channel.
C++ 0x is approved
The final ISO ballot on C++ 0x closed on Wednesday, and the result is just in: It have been unanimous approved.
It will now take a couple of month before the standard is published but we can probably call it C++11.
Congrats and good job to everyone involved…
Google C++ Style Guidelines
Google have compiled a set of style guidelines for there internal/external C++ use.
John Carmack QuakeCon Keynote
John Carmack annual QuakeCon Keynote is out.
He talks some about the usage of static analysis at Id Software, and he also announced that the Doom 3 source code will be released this year.
Update: Q&A Video




