No comments yet.
No trackbacks yet.
MongoDB substring search with a difference
about 2 months ago - No comments
It’s quite common to want to search a database for a key that starts with a given string. In SQL you have LIKE and in MongoDB you have regular expressions: But what if you want to do the inverse of this? i.e. to search the database for the keys that are themselves substrings of the More >
Home network crawler – cataloging every file on the home LAN with C# and MongoDB
about 5 months ago - 2 comments
With the addition of two more 3TB drives to the home network it’s becoming impossible to track files and to remember where each one is and whether it’s a backup of some other disk or not. There are 8 computers on the home network and over 10TB of storage distributed between them. Much of the More >
Stop writing rude software! Use LASTINPUTINFO instead.
about 5 months ago - No comments
Can you imagine what life would be like it people behaved like software programs do? You’d be working away on something when someone would interrupt, steal your attention, and demand a response. You’d be interrupted in the middle of sentences all the time and while you were dealing with one interruption someone else could come More >
C# Natural Language Engine connected to Microsoft Dynamics CRM 2011 Online
about 8 months ago - 1 comment
In an earlier post I discussed some ideas around a Semantic CRM. Recently I’ve been doing some clean up work on my C# Natural Language Engine and decided to do a quick test connecting it to a real CRM. As you may know from reading my blog, this natural language engine is already heavily used More >
Consultancy
about 1 year ago - No comments
Software Consultancy Serving the Greater Seattle Area Our consulting service is now open for business. We can help you with:- Business planning Program management Software Development for the Microsoft.NET platform Architectural advice and review Custom software development (offsite or onsite) Migrating web applications to ASP.NET MVC 2 Migration to Entity Framework 4 Complex threading using More >
Constrained parallelism for the Task Parallel Library
about 1 year ago - No comments
When developing .NET applications there is often the need to execute multiple background processes, for example, fetching and rendering different size thumbnails for images. Typically you queue actions like these onto the thread pool. But in the case of thumbnail generation you typically want to fetch a base image first and then perform the resize More >
Singleton tasks: A TaskFactory for the Task Parallel Library with ‘run-only-one’ semantics
about 1 year ago - No comments
When developing .NET applications there is often the need to execute some slow background process repeatedly. For example, fetching a feed from a remote site, updating a user’s last logged in time, … etc. Typically you queue actions like these onto the thread pool. But under load that becomes problematic as requests may be coming More >
GDI+ Image.FromFile has a problem – here’s how to fix it
about 1 year ago - No comments
In GDI+ you can call Image.FromFile to load an image from a file. BUT there are several issues with this call, the biggest being that GDI+ will keep the file open long after you are done with it. Here is an image loader that gets around this issue. If you are running a high volume More >
A simple redirect route handler for ASP.NET 3.5 routing
about 1 year ago - 3 comments
ASP.NET 3.5 Routing is a very powerful tool not just for registering routes for newer ASP.NET MVC applications but also for adding SEO friendly routes to older Webforms (ASPX) applications, or for routing multiple URLs to a single page. But that’s not all it can do. You can create your own IRouteHandler and then have More >
Why functional programming and LINQ is often better than procedural code
about 1 year ago - No comments
Functional programming is a relatively new component in the C# language. It can potentially replace for-loops in many situations with simpler code, but the question remains ‘what’s wrong with a good old for loop?’ Here are some of the reasons I think functional programming is important and in particular how LINQ can improve the readability, More >
Optimization Advice
Optimization is the root cause of much unmaintainable code. It is also the root cause of many bugs. My advice to the vast majority of programmers is to stay away from it: if you have a good architecture you should not need to optimize it at this level.
Personally I divide optimization into three buckets: 1. Optimization measured in seconds, 2. Optimization measured in milliseconds, 3. Optimization measured in microseconds.
#1 and #2 are worth doing, option #3 is rarely worth doing and most novices will often make performance worse not better when they attempt it.
For #1, start by reducing round trips to the server, set caching headers correctly, compress your JS and CSS files, … and follow the other advice Yahoo’s YSlow plugin offers.
#2 is usually concerned with your database architecture and the queries you are making. Novices often fetch too much data either breadth-wise (columns) or depth-wise (rows). Linq-to-Entities is a great help here for many developers because it defers the actual database work to the latest possible moment when all of the query parameters are known and thus does the least possible amount of work.
Many developers think that caching is the answer on #2 but I advise you to stay well away from trying to implement your own caching scheme. Use what’s provided for you in Linq-to-Entities or some other ORM but don’t try to roll you own, you are likely to introduce all manner of bugs related to stale data and concurrency issues. And if your queries aren’t efficient to begin with you application will not survive a restart under heavy load.
#3 is the hardest of all and the least likely to produce any benefit to the end user. Often it will be detrimental. My advice is to stay well away unless (i) you understand AMD and Intel processor architecture, and (ii) you have a loop that’s executed a billion times or more. Microsoft, Intel, AMD and others have spent decades optimizing inefficient code at the CPU and compiler level. Sadly this means that the cleverest algorithm can sometimes be significantly slower than the simplest ‘dumb’ algorithm. A tight loop doing a dumb linear search in O(n) can perform better than some clever tree search that theoretically runs in O(log(n)) time because the former can fit entirely in on-chip cache and can execute many times faster than the latter. If you are tempted to use a tree or other complex data-structure to ‘optimize’ access to a small number of items, think again: a simple array might be better and the code will probably be more maintainable and easier to read.
Overall, in terms of optimization, developers need to understand that CPU time is no longer a premium. These days the priorities are A) Network access, B) Disk access, C) Memory access, D) CPU time. If you can use a million CPU cycles to avoid some expensive disk access then it’s probably worth it. Too often I see people thinking they are ‘optimizing’ their code by stuffing a private member variable with some calculated value so they don’t have to recalculate it. Guess what, the calculation will take microseconds but the extra RAM you just used to store a million extra private member variables has now caused your application to page more often (both on-chip to off-chip and RAM to disk).
Before you do any optimization you should get a tool like JetBrain’s dotTrace, and for memory usage profiling, the Scitech .NET Memory Profiler. These will give you an insight into what needs fixing first and will help you understand where you can trim memory consumption.
Another key rule of optimization is to compare your development (and maintenance costs) for optimized code to the costs of a new server. You could easily spend more trying to get 10% performance gain than it would cost to just get a new quad-core server that will run 20% faster!