Ivan Krivyakov's Blog

Premature optimization is the root of all evil

August 22, 2012

PLinq and source IEnumerable thread safety

As I discovered that the source IEnumerable is called by PLINQ from multiple threads, it made me thinking: how can it possibly work? E.g. when someone writes code like this:

Enumerable.Range(1,1000).AsParallel()...

the Range iterator must keep its current state in some variable. If this state is accessed from multiple threads, how are race conditions avoided? Here are my findings in order:

1. Enumerable.Range() returns an IEnumerable<int>. This enumerable’s GetEnumerator() will return different enumerators for different threads. This appears to be a built-in feature of enumerables generated from yield return keyword. Reflector is my witness. Proof link.

Each enumerator, however, is not thread safe and does not have any locking code.

2. AsParallel() calls GetEnumerator() only once, and then uses it from multiple threads, so the above protection does not work.

3. Stephen Toub of Microsoft says, that as IEnumerable is inherently thread unsafe, PLINQ has locking built in.

4. As per Reflector it appears to be implemented in the PartitionedDataSoruce<T>.MoveNext() method.

So, relax folks. Your enumerator can and will be thread unsafe, PLINQ has its own locks to take care of that.

PLinq’s AsParallel() makes concurrent calls to underlying IEnumerable

I am trying to play with PLINQ, and I was wondering, if I have an enumerable that, say, reads lines from a file, or stock prices off Yahoo Finance, would AsParallel() call it from one thread or from multiple threads concurrently. Experiment shows that it’s the latter:

class Program
{
    [ThreadStatic]
    static int Index = 0;

    static IEnumerable GetStrings()
    {
        while (true)
        {
            yield return String.Format("Thread {0} String {1}", Thread.CurrentThread.ManagedThreadId, ++Index);
        }
    }

    static void Main(string[] args)
    {
        using (var writer = new ParallelTextWriter("out{0}.txt"))
        {
            GetStrings().AsParallel().Take(1000).ForAll(s => { writer.WriteLine(s); });
        }
    }
}

The output is

Thread 1 String 1
Thread 1 String 2
...
Thread 1 String 800
Thread 3 String 1
Thread 3 String 2
...
Thread 3 String 200

Obviously, the ratio of strings between threads (800/200 or 500/500) could be different each time.

August 21, 2012

Visual Studio Extensibility

Just write a quick macro for Visual Studio that would replace < with < and > with >, etc. I am probably the 1000th person to do that. Yet, it proved to be surprisingly hard.

  • DTE.ActiveDocument.Selection is an Object. No methods, no nothing. Need to cast to TextSelection to do anything useful with it.
  • TextSelection.ReplacePattern() happily replaces one pattern, then loses selection. Attempts to artificially restore selection failed, as TopPoint and BottomPoint properties are read only. MoveToPoint() did not do the trick either. I am still not sure how to tell the IDE to select the text from here to there.
  • If you attempt to do something like Selection.Text = Selection.Text.Replace((...) it works fine for one line, but for multiline selection it inserts lots of spaces and generally looks very weird. It also takes a lot of time and occasionally throws exceptions. A non starter.
  • Tried to use DTE.Find object, could not find a way to close programmatically the damn Find window. Fortunately DTE.Find.FindReplace() works without opening the window.

Oh yeah, if you try Googling for it – forget about it. You are drowning in crap. Bing is slightly better, but still no help there.

Final solution:


    Sub EscapeXmlChars()
        Replace("&", "&amp;")
        Replace("<", "&lt;")
        Replace(">", "&gt;")
    End Sub

    Sub UnescapeXmlChars()
        Replace("&lt;", "<")
        Replace("&gt;", ">")
        Replace("&amp;", "&")
    End Sub

    Private Sub Replace(ByVal find As String, ByVal replace As String)
        DTE.ActiveDocument.Activate()
        DTE.Find.FindReplace( _
        vsFindAction.vsFindActionReplaceAll, _
        find, _
        vsFindOptions.vsFindOptionsMatchInHiddenText, _
        replace, _
        vsFindTarget.vsFindTargetCurrentDocumentSelection)
    End Sub

August 13, 2012

Android Ice Cream Sandwitch (angry rant)

I got this update several weeks ago on my Motorola Razr, and it still feels bad, very bad. They broke so many things that did not need fixing:

1. Keyboard. Before I could switch languages by swiping on space bar. Now it’s an annoying pop-up that also leaves a notification in the notification bar: “select input method…”. WTH?

2. Keyboard again: Russian input is totally broken. Every word is underlined, and ridiculous spelling “corrections” are offered. If, however, I intentionally spell a word wrong, a correct fix is offered. So, the dictionary is fine, someone just messed up an “if” condition somewhere and never tested.

3. Maps. The “layers” button was previously always visible on top. I could, for example, turn traffic on and off while looking at directions or search. Now it is hidden below useless “results list” bar, so I need to cancel directions or search to make it visible again. Only today I found that “layers” is still visible in the menu.

4. Browser. The “windows” is no longer in the pop-up menu. Getting to it became a little piece of finger acrobatics. I need to scroll the page down to make the URL bar visible, and then quickly click on “Windows” button. If I don’t do that quickly enough, it goes away. Nicely done!

5. The “Windows” switcher itself now shows totally useless thumbnails that kinda get in the way. The phone screen is small as it is, and guess what: at this resolution all white pages look white and all black pages look black! The title or URL of the page as in the previous version was more than enough.

6. Ditto about application list. Application icons were just fine, I don’t want to see the stinking thumbnails!

7. “Favorites” applet on the home screen used to dial the selected number directly, while the one in “people” used to show you the list of numbers of the contact. That seemed kinda logical. They reversed the behavior in ICS. I don’t think there is a way to undo.

8. The icons in the notification bar became small and pretty much unreadable.

9. When an e-mail comes it shows a photo of the sender. Since most senders don’t have associated photos, it is just a giant white rectangle taking space and diverting your attention. AFAIK, there is no way to turn this off.

The good part is that in the browser you can now request desktop version of a page without dirty hacks (but you must load the mobile version first anyway). Also, this update allegedly enables GSM roaming, but I rarely use that.

I am not sure which of these problems come from Google and which from Motorola and, frankly, I don’t care. It looks like every time they come up with something good and you get used to it, it is bound to be erased in the next version by the marketing zealots. Better is the enemy of good, eh?

August 9, 2012

Silverlight Clipping Fun

While Silverlight animation performance may be better than WPF, its support for clipping is definitely inferior.

First off, there is no ClipToBounds property. If you want your canvas to clip its content, you need some extra code.

Then, it turns out that a TextBlock inside a canvas won’t clip itself. Basically, the “Width” property is ignored: the text will takScreen shote as much space as it sees fit. You can, however, tame a TextBlock by placing it inside a Border. This also gives a benefit of vertical alignment, that bare TextBlock cannot do.

Sample

Screenshot

The sample is generate by this code:

<Border Width="300" Height="300" BorderBrush="Blue" BorderThickness="1">
    <Canvas>
        <Border Width="50" BorderBrush="Black" BorderThickness="1" Canvas.Left="30" Canvas.Top="30">
            <TextBlock Text="This TextBLock is 50 pixels wide" />
        </Border>

        <Border Width="300" Height="100" BorderBrush="Brown" BorderThickness="1" Canvas.Left="30" Canvas.Top="80">
            <TextBlock Text="Centered text" HorizontalAlignment="Center" VerticalAlignment="Center" />
        </Border>
        
        <TextBlock Width="10" Text="This TextBlock is 10 pixels wide" Canvas.Left="150" Canvas.Top="250" />
    </Canvas>
</Border>

Silverlight Animation Performance

I am an experimenting with a Silverlight port of a WPF control, and find all kinds of funny things about Silverlight.

The good news is that Silverlight team seems to pay a lot of attention to performance. I have an animation of a dozen or so visuals: same code shared by WPF and Silverlight project. WPF animation works fine on a modern machine, but staggers hopelessly on older computer (3.2GHz Pentium 4, Matrox Millenium G450 video card). Silverlight animation works great on the same old computer.

It’s too bad Silverlight is dead and being replaced with WinRT :(