MonoTorrent and advanced C#

Alan wrote about profiling MonoTorrent.

He has some specific cases where GC is causing him issues. He gives some examples in the form of “I want to GC here”. I hate to be a nay sayer, but… well… NAY! 🙂 I’m a big fan of allowing GC to function. If you think you can outsmart GC, then you are wrong. If you think you need to, then there is something wrong with your model. I say don’t call GC.Collect().

Now in Allan’s first example, ignoring memoization as purhaps a better way, if the issue is that Example() is going to be called a large number of times, allocating many MyObject instances, then purhaps using an advanced C# feature is in order. C# does allow for stack based allocation. It requires the code to be marked unsafe, but it is likely that this use case is EXACTLY why this feature is included in the language. This isn’t Java that we are dealing with here! (small jab-hehe)

public unsafe static void Example() {
MyObject *pa = stackalloc MyObject[1];
MyObject a = *pa;
a.x = 15;
a.DoACalculation();
}

Of course, this requires that MyObject be a value type and not a reference type (struct, not class). And in my testing on Mono, I could not get this to perform better than simpy using new but using a struct instead of a class. So maybe refactoring a class to a struct would help performance. It maybe a good first step to see if it helps before going unsafe.

I must admit that I’m not sure I’m benchmarking this properly. I’m really just using this program. If anyone can shed some light on best practice here, I would appreciate it.


using System;
public class StackAllocExample {
public static void Main() {
Console.WriteLine("stackalloc");
DateTime start = DateTime.Now;
Console.WriteLine(start);
for(int i = 0 ; i < 100000000; i++ ){ Example(); } DateTime stop = DateTime.Now; Console.WriteLine(stop); Console.WriteLine(stop-start); start = DateTime.Now; Console.WriteLine(start); for(int i = 0 ; i < 100000000; i++ ){ SafeExample(); } GC.Collect(); stop = DateTime.Now; Console.WriteLine(stop); Console.WriteLine(stop-start); Console.WriteLine("heap alloc struct"); start = DateTime.Now; Console.WriteLine(start); for(int i = 0 ; i < 100000000; i++ ){ SafeStructExample(); } GC.Collect(); stop = DateTime.Now; Console.WriteLine(stop); Console.WriteLine(stop-start); } public unsafe static void Example() { MyObject *pa = stackalloc MyObject[1]; MyObject a = *pa; a.x = 15; a.DoACalculation(); } public static void SafeExample() { MyRObject a = new MyRObject(); a.x = 15; a.DoACalculation(); } public static void SafeStructExample() { MyObject a = new MyObject(); a.x = 15; a.DoACalculation(); } } struct MyObject { public int x; public void DoACalculation() { ResultFromCalculation = x+1; } public int ResultFromCalculation; } struct MyRObject { public int x; public void DoACalculation() { ResultFromCalculation = x+1; } public int ResultFromCalculation; }

Martin Taylor and Bill Hilf on Linux at Microsoft

I have no idea why this old video (and part 2) shows up in this rss feed, but I am watching it.

It is interesting to hear Microsofts perspective on Linux and Open Source and how different it is from every Open Source user I know. It is also interesting to hear what Open Source means to Microsoft and how different the benefits are to Microsoft vs. those who use Open Source.

It is over a year old. I wonder if they have learned anything in the past year.

I can do in 2 lines of C# code what take 4 lines of VB.NET

I program in .NET. It is unavoidable, at some point you will be asked about C# vs. VB.NET. Personally I could care less. I prefer C#. I’m not even sure why. I grew up BASIC (Atari Basic, Amiga Basic, GW-Basic and QBasic). Later I switched to curly braces for high school (C) and college(C++). Along the way I used a number of langauges which also use semicolons and curly braces (php, perl, and pike). So I definitely became a curly brace kind of guy. Even though I did use Visual Basic, Visual Basic for Applications, and VBScript over the same time period, I simply felt more at home in C or C++.

So, next time some VB.NET lover tries to make an argument for VB.NET over C#, I’ll be ready. I’d give an example here, but I can never understand these arguments or even the underlying statements. They are usually so nonsensical. I rarely remember things that I don’t undersand, so I’m lucky enough that their convoluted arguments go in one ear and right out the other. Next time I am ready! I guess I shall try to remember this retort from
http://worldofcoding.blogspot.com/2006/11/numericupdown-is-nice-control-eh.html

[C#]
foreach ( Control c in numericUpDown1.Controls )
tooltip.SetToolTip( c, “mytooltip” );

[Visual Basic]
Dim c As Control
For Each c In numericUpDown1.Controls
tooltip.SetToolTip(c, “mytooltip”)
Next

4 lines of VB.NET equals 2 lines of C#!

I feel much the same about the old csh vs. sh vs ksh. I just don’t care. But I don’t have any good examples for why I prefer bash.

Dot Net Rocks! best show ever!

I just listened to the lastest episode of .Net Rocks! and I have to say it was one of the best shows yet. Why was is so great? Well, I am so glad that I asked. Ann Arbor was in the house. Diane Marsh and Bill Wagner were the guests and they were talking about “Non-MS Technology”. Don’t get me wrong, they related all of it to .NET, but it was great to hear them talking about Python, Turbogears, even Java and Groovy. I’ve been hearing a lot about groovy, and after reading the front page I’ll just call it Java’s Boo. Maybe it is because they are both hosted at The Codehaus. I prefer Boo. 🙂

Even if you could care less about .NET, give this show a listen. It is very interesting to hear a VB.NETer’s (Carl) take on whitespace meaning in Python. It is funny to hear because I remember having the reaction 10 years ago, and so I feel like I’m getting in touch with myself from when I first looked at python.

The show ended with the announcement that you can win tickets to CodeMash! AWESOME! I really wish I could make it to CodeMash.

P.S. Visual Studio 2005 has made me wait for 2 minutes for the last time. I’ve removed the F1 keybinding. I occasionally slip and press F1 and it makes my system unusable for 2 minutes while Visual Studio Help launches. Much like James Belushi in The Principal, I have said “NO MORE!”

Novell Open Audio on iFolder

I’m listening to Novell Open Audio and immediately at the start of the show I’m thinking “Jorge must have nagged these guys for this show”. And I keep listening and it has some great information, not just about the product, but also about the development process. iFolder design has been “temporarily” taken in house. I find this interesting because the software is open source and under the GPL, yes the process of creating the software is not transparent. The project looks dead. This podcast is much in response to the fact that the project looks dead. Yet we are assured by Novell that work is being done.

I find this very interesting because it is a very different open source model than most people think of when they think open source like Linux, Apache, CastleProject. These projects are developed by the public, in the public. But iFolder is developed by Novell, and during this time period, under closed doors.

I make no judgment about if this is good or bad. I don’t care. I’m not an open source or transparency insane person. I just point it out because I find it interesting.

About 10min into the podcast, Ted comes right out and says “If you are an Ubuntu fanboy… my friend Jorge Castro” Hahahaha. My initial suspicions were correct. Thanks for nagging the right people Jorge.

Visual Studio tip of the century

Thanks hongmeig! Open File the fastest way

OMG I’ve been looking for this since November 2005. I often felt like everyone was in on a joke but me and that everyone knew this was built into Visual Studio except for me.

Press ctrl-/  (This take you to the ‘find in files’ textbox in the toolbar)  Now type “>of ” and start typing the name of the file which you wish to open. You will get a drop down of files which match. You can arrow down and press enter.

FINALLY a keyboard only “open file” which doesn’t require Alt-F-O (or ctrl-O) and arrow navigation of the directory heirarchy. I’m almost as happy as the time I discovered dictionary word completion in vim.

Querying Active Directory with Unix LDAP tools.

I want to run ldap queries against an AD, after all, AD is just LDAP, right?

Finding an AD server which to query can be done a number of ways. If you are on windows, an easy approach may be to use WMI or ADSI to ask AD where a domain controller is, but lets say you aren’t on windows. AD requires this information in DNS. One easy lucky way is server naming. You know that servers named Domain Controller or “DC” are probably a domain controller. I use the host command which comes with ISC BIND.


$ host -av myaddomain.myinetdomain.net

will give you a list (can be very long depending on your organization) of servers.

If that doesn’t show me what I what, I use this information How Domain Controllers are Located in Windows XP


$ host -av _ldap._tcp.myaddomain.myinetdomain.net

gives me a list of domain controllers which are listening for LDAP requests.

Now I can use ldapsearch to get the RootDSE. This doesn’t even require binding to the LDAP Directory


$ ldapsearch -x -h 192.168.199.10 -b '' -s base '(objectclass=*)'

Now the namingContexts attributes give me points off of which to start my searches. If you are familiar with AD then you should be familiar with these naming contexts. Of course one reflects my ad. e.g. dc=myaddomain,dc=myinetdomain,dc=net

If you happen to be in a large organization, take notice about some hints an helpers here. The serverName attribute often reflects the organizational structure of the AD. Is the AD organized by geography, business unit, or something else? The organizational unit in which this server is placed can give you hints.

From this point on you need to bind to the active directory. Now your account could be in any OU, so how do you know if you are cn=jsmith,cn=salespeople,cn=blah….. or if you are cn=jsmith,cn=Users,cn=blah… Well, quite cleverly, Microsoft extended the LDAP spec a bit and allows for binding with what they call a “User Principal Name”. You can login much like you would to a Windows computer.


$ ldapsearch -x -h 192.168.199.10 -b 'dc=myaddomain,dc=myinetdomain,dc=net' -s base -D 'jsmith@myaddomain.myinetdomain.net' -W

We know the domain portion of the User Principal Name from our naming contexts search before.

Now we can build all sorts of nice LDAP search expressions. Want to see all the computers in the domain?


$ ldapsearch -x -h 192.168.199.10 -b 'dc=myaddomain,dc=myinetdomain,dc=net' -s base -D 'jsmith@myaddomain.myinetdomain.net' -W '(objectclass=Computer)'

You can use AD’s Abiguous Name Resolution:


$ ldapsearch -x -h 192.168.199.10 -b 'dc=myaddomain,dc=myinetdomain,dc=net' -s base -D 'jsmith@myaddomain.myinetdomain.net' -W '(anr=smith*)'

Ultimately I want to search for computers in the Active Directory which have not been used in a while. Forgetting for a moment that lastLogon is not replicated in AD, how can we do this? or how can we even tell what that lastLogon value means. When I look at my ldap entry I get this for the lastLogon attribute:


$ ldapsearch -x -h 192.168.199.10 -b 'dc=myaddomain,dc=myinetdomain,dc=net' -s base -D 'jsmith@myaddomain.myinetdomain.net' -W '(anr=smith*)' lastLogon
...
accountExpires: 9223372036854775807
lastLogon: 128082628734460625
pwdLastSet: 128074920542439359

It turns out (and this is no joke) that this number is the time in some ANSI standard that is the number of 100 nanosecond intervals since January 1st, 1601. Ugh… There is much good information about this in the Dandelions technet article. I solved the problem of reading this using pythons AWESOME datetime module.


#!env python  from sys import argv
from datetime import datetime,timedelta
ansiTimeStart = datetime(1601,1,1)
lastLogon = timedelta(seconds= long(argv[1]) / 10000000)
#rfc822- with borked timezone 
if len(argv) and argv[2]=='-r':
print (ansiTimeStart+lastLogon).strftime("%a, %d %b %Y %H:%M:%S +0000" )
else:
#or ISO 8601
print (ansiTimeStart+lastLogon).isoformat()

So now I can send one of those crazy ansi dates and get a real date in either rfc822 format or iso8601 format.


$ ./ansidate 128082628734460625 -r
Fri, 17 Nov 2006 18:47:53 +0000
$ ./ansidate 128082628734460625
2006-11-17T18:47:53

Now what if I want to query for all computer records in a domain which have not had thier password set since August 1st, 2006. I have to find that crazy date. I just use python interactive for this.


$ python
...
>>>(datetime(2006,8,1)-datetime(1601,1,1)).days*3600*24*10000000
127988640000000000L

Now I can search.


$ ldapsearch -x -h 192.168.199.10 -b 'dc=myaddomain,dc=myinetdomain,dc=net' -s base -D 'jsmith@myaddomain.myinetdomain.net' -W '(&(lastLogon< =127988640000000000)(objectclass=computer)'

Note that ldap search filters don't have a less than operator, you must use less than or equal. a filter of '(lastLogin>1)' will fail with a Bad search filter error.

Using LDAP to query Active Directory is a natural fit, especially if you have LDAP experience in other applications. All of your LDAP knowledge should be applicable to Active Directory. I've found that much of the details on the AD schema attributes are not mentioned in most Microsoft documentation. It is best to go directly to the Windows SDK. Each attribute is well documented there.

debugging late bound code

I have a Windows Service that uses a plugin architecture for some things. I couldn’t figure out why I couldn’t step through one of the plugin modules. I checked that my plugin system wasn’t actually running in a separate app domain (not that it should matter) and it wasn’t. I have that set as a runtime configuration option, but no, only one app domain here. I scratched my head some more and took a look at my plugins directory. DUH! I stopped copying the pdb files (the debug symbol files) on build.

So if you run into the dreaded “cannot find source”, just remember that you must have the pdb files along side the dlls.

I didn’t find much when googling for this except for this link:
http://www.thescripts.com/forum/thread251214.html

Firefox Windows Authentication

Hey, this is awesome! So much nicer than using Firefox’s save password functionality. If I’m logged into a domain, and the website is on IIS with all that “windows auth” magic that automatically lets you in when using IE… well… I get that functionality in Firefox!

Thanks to Eric Wise!

basically, just add hostnames for which you wish to allow this type of authentication (a little more work than IE, a lot more security) to the following preferences in about:config : network.automatic-ntlm-auth.trusted-uris, network.negotiate-auth.delegation-uris, network.negotiate-auth.trusted-uris.

http://codebetter.com/blogs/eric.wise/archive/2006/11/16/Note-to-self_3A00_-Firefox-Windows-Authentication.aspx

Nostalgy Extension for Thunderbird is a must have

I just installed this extension and the ESC-ESC, L, ESC-M and G keybindings are enough to make it worthwhile.

I found it here: http://micke.hallendal.net/archives/2006/11/a_must_for_all.html

The G keybinding is the golden feature. It lets you quickly navigate (Goto) any folder. I still use n for next unread and b and f for previous and next message, but being able to use the arrow keys to navigate both the message list, and the message itself without clicking between panes, and without getting lots in tabstops is very nice. Just ESC-m to select the message pane and ESC-ESC to select the folder pane.

Jorge wants to know what Evolution has to offer in this area. Jorge also doesn’t care, because he uses a mouse.