Category Archives: Tip

How to quickly convert all NTEXT columns to NVARCHAR(MAX) in a SQL Server database

I was at a client’s earlier today and the question came up of how to convert all NTEXT columns to NVARCHAR(MAX) in their SQL Server databases, and it turns out they have rather a lot of them.

There are a couple of obvious advantages to this conversion:

  1. Online index rebuilds with SQL Server Enterprise Edition become a possibility,
  2. Values are stored in row by default, potentially yielding performance gains.

My response to this was, “Yeah, sure: I can write a script to do that.” Two seconds after I said this I thought, “Hmm, I bet 30 seconds of Googling will provide a script because this must have come up a zillion times before.”

Sure enough, there are some pretty reasonable hits. For example, http://stackoverflow.com/questions/18789810/how-can-i-easily-convert-all-ntext-fields-to-nvarcharmax-in-sql-query.

Buuuuuuuuuuuut as ever, you’d be naive indeed to think that you can just copy and paste code from StackOverflow and have it work first time. Moreover, even with modification, you need to go over it with a fine-toothed comb to make sure you’ve squashed every last bug.

For example, this boned me earlier because I wasn’t paying proper attention:

CASE WHEN is_nullable = 1 THEN 'NOT' ELSE '' END

You can see the logic is reversed from what it should be.

So, anyway, I ended up concocting my own, of which you can find the latest version at https://github.com/bartread/sqlscripts/blob/master/scripts/AlterAllNtextColumnsInDbToNvarcharMax.sql.

There are essentially three phases:

  1. Change the datatype of the NTEXT columns to NVARCHAR(MAX) using ALTER TABLE statements
  2. Pull any values small enough to fit in row out of LOB storage and back into rows using UPDATE statements. Thanks to John Conwell for pointing out the necessity of doing that to realise any performance increase with existing data.
  3. Refresh the metadata for any views using sp_refreshview – this makes sure that, for example, columns listed for them in sys.columns have the correct data type.

Phases 1 and 2 are actually done together in a loop for each NTEXT column in turn, whilst phase 3 is done in a separate loop at the end. I just refresh the metadata for all views because, although I could figure out only the views that depend on the tables, it’s simpler to just do them all and doesn’t take that long. Of course, if you have thousands of views and a relatively small number of NTEXT columns you might want to rethink this. My situation is numbers of tables, views, and NTEXT columns are all of the same order of magnitude so a simple script is fine.

For those of you who don’t have git installed, or aren’t comfortable with DVCS, here’s the full script:

USE _YOUR_DATABASE_NAME_
GO

SET NOCOUNT ON;

-- Set this to 0 to actually run commands, 1 to only print them.
DECLARE @printCommandsOnly BIT = 1;

-- Migrate columns NTEXT -> NVARCHAR(MAX)

DECLARE @object_id INT,
      
@columnName SYSNAME,
      
@isNullable BIT;

DECLARE @command NVARCHAR(MAX);

DECLARE @ntextColumnInfo TABLE (
  
object_id INT,
  
ColumnName SYSNAME,
  
IsNullable BIT
);

INSERT INTO @ntextColumnInfo ( object_id, ColumnName, IsNullable )
  
SELECT  c.object_id, c.name, c.is_nullable
  
FROM    sys.columns AS c
  
INNER JOIN sys.objects AS o
  
ON c.object_id = o.object_id
  
WHERE   o.type = 'U' AND c.system_type_id = 99;

DECLARE col_cursor CURSOR FAST_FORWARD FOR
   SELECT
object_id, ColumnName, IsNullable FROM @ntextColumnInfo;

OPEN col_cursor;
FETCH NEXT FROM col_cursor INTO @object_id, @columnName, @isNullable;

WHILE @@FETCH_STATUS = 0
BEGIN
   SELECT
@command =
      
'ALTER TABLE '
      
+ QUOTENAME(OBJECT_SCHEMA_NAME(@object_id))
           +
'.' + QUOTENAME(OBJECT_NAME(@object_id))
       +
' ALTER COLUMN '
      
+ QUOTENAME(@columnName)
       +
' NVARCHAR(MAX) '
      
+ CASE
          
WHEN @isNullable = 1 THEN ''
          
ELSE 'NOT'
        
END
      
+ ' NULL;';
      
  
PRINT @command;
  
IF @printCommandsOnly = 0
  
BEGIN
       EXECUTE
sp_executesql @command;
  
END

   SELECT @command =
      
'UPDATE '
      
+ QUOTENAME(OBJECT_SCHEMA_NAME(@object_id))
           +
'.' + QUOTENAME(OBJECT_NAME(@object_id))
       +
' SET '
      
+ QUOTENAME(@columnName)
       +
' = '
      
+ QUOTENAME(@columnName)
       +
';'

   PRINT @command;
  
IF @printCommandsOnly = 0
  
BEGIN
       EXECUTE
sp_executesql @command;
  
END

   FETCH NEXT FROM col_cursor INTO @object_id, @columnName, @isNullable;
END

CLOSE col_cursor;
DEALLOCATE col_cursor;

-- Now refresh the view metadata for all the views in the database
-- (We may not need to do them all but it won't hurt.)

DECLARE @viewObjectIds TABLE (
  
object_id INT
);

INSERT INTO @viewObjectIds
  
SELECT o.object_id
  
FROM sys.objects AS o
  
WHERE o.type = 'V';

DECLARE view_cursor CURSOR FAST_FORWARD FOR
   SELECT
object_id FROM @viewObjectIds;

OPEN view_cursor;
FETCH NEXT FROM view_cursor INTO @object_id;

WHILE @@FETCH_STATUS = 0
BEGIN
   SELECT
@command =
      
'EXECUTE sp_refreshview '''
      
+ QUOTENAME(OBJECT_SCHEMA_NAME(@object_id)) + '.' + QUOTENAME(OBJECT_NAME(@object_id))
       +
''';';
      
  
PRINT @command;

   IF @printCommandsOnly = 0
  
BEGIN
       EXECUTE
sp_executesql @command;
  
END

   FETCH NEXT FROM view_cursor INTO @object_id;
END

CLOSE view_cursor;
DEALLOCATE view_cursor;
GO

NOTE: this won’t work where views are created WITH SCHEMABINDING. It will fail at ALTER TABLE for any table upon which schemabound views depend. Instead, to make it work, you have to DROP the views, then do the ALTERs and UPDATEs, then re-CREATE the views. Bit of a PITA but there’s no way around it unfortunately. I didn’t need to worry about this because my client doesn’t use schemabound views.

Of course it goes without saying that you should back up your database before you run any script like this!

To use it you just need to substitute the name of your database where it says _YOUR_DATABASE_NAME_ at the top of the script.

Also, As with automating many tasks in SQL Server, dynamic SQL is a necessity. It’s a bit of a pain in the backside so a @printCommandsOnly mode is advised for debugging purposes, and I’ve switched this on by default. You can copy and paste the commands into a query window, parse them, or even execute them to ensure they work as expected.

Once you’re happy this script does what you want set the value of @printCommandsOnly to 0 and rerun it to actually execute the commands it generates.

You might wonder why I’ve written this imperatively rather than in set-based fashion. Well, it’s not just because I’m a programmer rather than a DBA. In fact the original version, which you can still see if you look at the file’s history, was set-based. It looked pretty much like this:

USE _YOUR_DATABASE_NAME_
GO

-- Migrate columns NTEXT -> NVARCHAR(MAX)

DECLARE @alterColumns NVARCHAR(MAX) = '';
SELECT  @alterColumns = @alterColumns
  
+'ALTER TABLE '
  
+ QUOTENAME(OBJECT_SCHEMA_NAME(c.object_id)) + '.' + QUOTENAME(OBJECT_NAME(c.object_id))
   +
' ALTER COLUMN '
  
+ QUOTENAME(c.Name)
   +
' NVARCHAR(MAX) '
  
+ CASE WHEN c.is_nullable = 1 THEN '' ELSE 'NOT' END + ' NULL;'
  
+ CHAR(13)
   +
'UPDATE '
  
+ QUOTENAME(OBJECT_SCHEMA_NAME(c.object_id)) + '.' + QUOTENAME(OBJECT_NAME(c.object_id))
   +
' SET '
  
+ QUOTENAME(c.Name)
   +
' = '
  
+ QUOTENAME(c.Name)
   +
';' + CHAR(13) + CHAR(13)
FROM    sys.columns AS c
INNER JOIN sys.objects AS o
ON c.object_id = o.object_id
WHERE   o.type = 'U' AND c.system_type_id = 99; --NTEXT

PRINT @alterColumns;

EXECUTE sp_executesql @alterColumns;
GO

-- Update VIEW metadata

DECLARE @updateViews NVARCHAR(MAX) = '';
SELECT @updateViews = @updateViews
  
+ 'EXECUTE sp_refreshview '''
  
+ QUOTENAME(OBJECT_SCHEMA_NAME(o.object_id)) + '.' + QUOTENAME(OBJECT_NAME(o.object_id))
   +
''';' + CHAR(13)
FROM sys.objects AS o
WHERE o.type = 'V'

PRINT @updateViews;

EXECUTE sp_executesql @updateViews;
GO

It’s certainly a lot less code, which is nice. And it doesn’t use CURSORs, which is also nice.

However, it does have problems:

  • The PRINT statement in T-SQL truncates output if it goes beyond a certain length. I don’t know exactly what this length is off the top of my head, but my generated scripts were more than long enough to reach it.
  • The result of this is you can’t copy and paste the complete generated script into another query window, so it might make debugging a bit trickier in some instances.
  • The really problematic thing is that, when something goes wrong, you can’t necessarily relate it back to the exact command that failed, whereas the imperative version makes this easy since each generated command is executed individually.

So I threw away the, on the face of it, "cleverer" and more "elegant" set-based version in favour of the longer, clunkier (but easier to debug) imperative version.

I hope you find it useful and please feel free to submit patches, pull requests, bug reports, feature requests via the main project GitHub page at https://github.com/bartread/sqlscripts. (Turns out I’m building up a small library of handy scripts so I’ll be pushing a few more items into this repo in due course.)

The Spike Board: A Quick Agile Solution for Managing and Visualising Tech Spikes and Bug Bashes

I’ve recently been fortunate enough to start working with comparethemarket.com as one of my clients, specifically with their home team, who deal with their home insurance site. These guys are fully awesome, and I’m having a really good time.

What I want to do with this post is share with you a way in which we reorganised one of our agile boards, in a way that you might find helpful.

CTM make heavy use of agile techniques, to the point where bugs are often not filed in any kind of tracker (we use Mingle, when we use anything at all), but instead appear as cards on the appropriate board. The past couple of days we’ve been doing a bug bash in the run up to a release of some new functionality, and we’d written all the areas that needed testing as a big list on one of the boards.

People would pick areas for testing, write their initials by them, and mark them as completed either by ticking or crossing them off the list. Bugs were written in a separate list at the bottom of the board in the order they were encountered. After some discussion, some items we decided we didn’t care about or postponed until later, both test and bugs.

As you can imagine the board’s starting to look pretty messy at this point. Not a problem for those of us who’ve been around the whole time, but a couple of the team had been out and, at the standup this morning, it became clear that our board wasn’t really doing a great job of communicating:

  • what we’d done
  • what was left to do
  • what we’d decided not to do
  • what each of the items (test areas and bugs) actually meant

Lightweight is good but we’d probably gone a bit too far in that direction and, in fact, there was quite a bit of confusion.

The net result is we had to go through each item one by one. It didn’t take absolutely ages, but it was somewhat time-consuming.

So… we decided to rework the board to make it clearer to anyone and everyone what was happening and where we were in the process.

Here’s what we came up with for the “work item” board, where a work item is either an area for test, or a bug.

proposedworkitemboard

The basic idea is that work items are written on cards and start in the top left under proposed. They then migrate either to rejected or done on the bottom right. Obviously cards can skip over stages – so they can move directly from proposed to accepted, for example.

Note that rejected doesn’t mean rejected for all time: it just means we’ve chosen not to do something in this tech spike.

Bug prioritisation was another issue so we came up with this, although we haven’t yet needed it. In future though, when bugs are found we can write them on cards and stick them on another board that looks like this:

proposedbugboard

The axes are severity on the left (high or low) and incidence (alternatively hit probability) at the bottom. Priorities are shown in red – we just pick off the bugs in priority order. It’s rough and ready but should make it easy to prioritise.

You can obviously choose different axes that are more relevant for you if you like. Likewise, if you have different states for your work items than we use, or you have more or less of them, go ahead and use them.

Bugs that we’re fixing then become work items (on different coloured cards) that go back on the work item board, probably going straight into accepted. We probably lift them directly from the bugs board and place them on the work item board – thus the bugs board only contains live bugs we’re not actively working on.

Work item cards look like this:

proposedworkcard

Everything apart from the title and name(s) are optional, to keep it as lightweight as possible. We could just use avatars instead of names – we all have little stickies with our chosen avatar on that we add to any cards we’re working on. For things that are done it might be handy to use names so we don’t need to create loads of avatar stickies for everyone.

The cards on the bug board would be similar, but just with a title and description (optional). Potentially we could transfer them from the bug board to the work item board when we start working on them so that (i) we’re not duplicating cards, and (ii) it’s easy to see how many outstanding bugs there are.

Here’s what our work item board now looks like:

reorganisedworkitemboard

(Note that we decided not to add everything we’d already done to the new board, which comprised around two thirds of the total work items, but we took a photo as a backup so we have a record of the areas we need to test for future releases, and we’ll use the new board layout in future instead of the vanilla list.)

As you can see, it’s easy to understand:

  • the state of work items
  • how much WIP we have
  • how much is done
  • how much is left to do

Hopefully some of you will find this helpful as well.

Timing is everything in the performance tuning game: learn to choose the right metrics to hunt down bottlenecks

So much of life is about timing. Just ask David Davis. He was arrested after getting into a scuffle whilst having his hair cut:

David Davis with half a haircut in his police mugshot.

Bad timing, right?

But that’s not really the kind of timing I’m talking about. When you’re performance tuning an application an understanding of timing is crucial to success – it can reveal truth that would otherwise remain masked. In this post I want to cover three topics:

  • The different types of timing data you can collect, and the best way to use them,
  • Absolute versus relative timing measures, and
  • The effect of profiling method (instrumentation versus sampling) on the timing data you collect.

Let’s start off with the first…

Regardless of your processor architecture, operating system, or technology platform most (good) performance profiling software will use the most accurate timer supported by your hardware and OS. On x86 and x64 processors this is the Time Stamp Counter, but most other architectures have an equivalent.

From this timer it’s possible to derive a couple of important metrics of your app’s performance:

  • CPU time – that is, the amount of time the processor(s) spend executing code in threads that are part of your process ONLY – i.e., exclusive of I/O, network activity (e.g., web service or web API calls), database calls, child process execution, etc.
  • Wall clock time – the actual amount of time elapsed executing a particular piece of code, such as a method, including I/O, network activity, etc.

Different products might use slightly different terminology, or offer subtly differing flavours of these two metrics, but the underlying principles are the same. For this post I’ll show the examples using ANTS Performance Profiler but you’ll find that everything I say is also applicable to other performance tools, such as DotTrace, the Visual Studio Profiling Tools, and JProfiler, so hopefully you’ll find it useful.

The really simple sequence diagram below illustrates the differences between CPU time and wall clock time for executing a method called SomeMethod(), which we’ll assume is in a .NET app, that queries a SQL Server database.

Sequence diagram illustrating the difference between wall clock and CPU time.

The time spent actually executing code in SomeMethod() is represented by regions A and C. This is the CPU time for the method. The time spent executing code in SomeMethod() plus retrieving data from SQL Server is represented by regions A, B, and C. This represents the wall clock time – the total time elapsed whilst executing SomeMethod(). Note that, for simplicity’s sake:

  • I’ve excluded any calls SomeMethod() might make to other methods in your code, into the .NET framework class libraries, or any other .NET libraries. Were they included these would form part of the CPU time measurement because this is all code executing on the same thread within your process.
  • I’ve excluded network latency from the diagram, which would form part of the wall clock time measurement.

Most good performance profilers will allow you to switch between CPU and wall clock time. All the profilers I mentioned above support this. Here’s what the options look like in ANTS Performance Profiler; other products are similar:

Timing options in Red Gate's ANTS Performance Profiler

There’s also the issue of time in method vs. time with children. Again the terminology varies a little by product but the basics are:

  • Time in method represents the time spent executing only code within the method being profiled. It does not include callees (or child methods), or any time spent sleeping, suspended, or out of process (network, database, etc.). It follows from this that the absolute value of time in method will be the same regardless of whether you’re looking at CPU time, or wall clock time.
  • Time with children includes time spent executing all callees (or child methods). When viewing wall clock time it also includes time spent sleeping, suspended, and out of process (network, database, etc.).

OK, let’s take a look at an example. Here’s a method call with CPU time selected:

CPU times for method

And here’s the same method call with wall clock time selected:

Wall clock times for method

Note how in both cases Time (ms), which represents time in method, is the same at 0.497ms, but that with wall clock time selected the time with children is over 40 seconds as opposed to less than half a second. We’ll take a look at why that is in a minute. For now all you need to understand is that this is time spent out of process, and it’s the kind of problem that can easily be masked if you look at only CPU time.

All right, so how do you know whether to look at CPU time or wall clock time? And are there situations where you might need to use both?

Many tools will give you some form of real-time performance data as you use them to profile your apps. ANTS Performance Profiler has the timeline; other tools have a “telemetry” view, which shows performance metrics. The key is to use this, along with what you know about the app to gain clues as to where to look for trouble.

The two screengrabs above are from a real example on the ASP.NET MVC back-end support systems for a large B2B ecommerce site. They relate to the user clicking on an invoice link from the customer order page. As you’d expect this takes the user to a page containing the invoice information, but the page load was around 45 seconds, which is obviously far too long.

Here’s what the timeline for that looked like in ANTS Performance Profiler:

ANTS Performance Profiler timeline for navigating from order to invoice page on internal support site.

(Note that I’ve bookmarked such a long time period not because the profiler adds that much overhead, but because somebody asked me a question whilst I was collecting the data so there was a delay before a clicked Stop Live Bookmark!)

As you can see, there’s very little CPU activity associated with the worker process running the site; just one small spike over to the left.

This tells you straight away that the time isn’t being spent on lots of CPU intensive activity in the website code. Look at this:

Call tree viewing CPU time - doesn't look like there's much amiss.

We’re viewing CPU time and there’s nothing particularly horrendous in the call tree. Sure, there’s probably some room for optimisation, but absolutely nothing that would account for the observed 45 second page load.

Switch to wall clock time and the picture changes:

Call graph looking at wall clock time - now we're getting somewhere!

Hmm, looks like the problem might be those two SQL queries, particularly the top one! Maybe we should optimise those*.

Do you see how looking at the “wrong” timing metric masked the problem? In reality you’ll want to use both metrics to see what each can reveal and you’ll quickly get to know which works best in different scenarios as you do more performance tuning.

By the way: for those of you working with Java, JProfiler has absolutely great database support with multiple providers for different RDBMSs. I would highly recommend you check it out.

You may have noticed that throughout the above examples I’ve been looking at absolute measurements of time, in this case milliseconds. Ticks and seconds are often also available, but many tools often offer relative measurements – generally percentages – in some cases as the default unit.

I find relative values often work well when looking at CPU time but that, generally, absolute values are a better bet for wall clock time. The reason for this is pretty simple: wall clock time includes sleeping, waiting, suspension, etc., and so often your biggest “bottleneck” can appear to be a single thread that mostly sleeps, or waits for a lock (e.g., the Waiting for synchronization item in the above screenshots). This will often be something like the GC thread and the problem is, without looking at absolute values, you’ve no real idea how significant the amounts of time spent in other call stacks really are. Switching to milliseconds or (for really gross problems – the above would qualify) seconds can really help.

Let’s talk about instrumentation versus sampling profiling and the effect this has on timings.

Instrumentation is the more traditional of the two methods. It actually modifies the running code to insert extra instructions that collect timing values throughout the code. For example, instructions will be inserted at the start and end of methods and, depending upon the level of detail selected, at branch points in the code, or at points which mark the boundaries between lines in the original source. Smarter profilers need only instrument branch points to accurately calculate line level timings and will therefore impose less overhead in use.

Back in the day this modification would be carried out on the source code, and this method may still be used with C++ applications. The code is modified as part of the preprocessor step. Alternatively it can be modified after compilation but before linking.

Nowadays, with VM languages, such as those that run in the JVM or the .NET CLR, the instrumentation is generally done at runtime just before the code is JITed. This has a big advantage: you don’t need a special build of your app in order to diagnose performance problems, which can be a major headache with older systems such as Purify.

Sampling is available in more modern tools and is a much lower overhead, albeit less detailed, method of collecting performance data. The way it works is that the profiler periodically takes a snapshot of the stack trace of every thread running in the application. It’ll generally do this many times a second – often up to 1,000 times per second. It can then combine the results from the different samples to work out where most time is spent in the application.

Obviously this is only good for method level timings. Moreover methods that execute very quickly often won’t appear in the results at all, or will have somewhat skewed timings (generally on the high side) if they do. Timings for all methods are necessarily relative and any absolute timings are estimates based on the number of samples containing each stack trace relative to the overall length of the selected time period.

Furthermore most tools cannot integrate ancillary data with sampling. For example, ANTS Performance Profiler will not give information about database calls, or HTTP requests, in sampling mode since this data is collected using instrumentation, which is how it is able to tell you – for example – exactly where queries were executed.

Despite these disadvantages, because of its low overhead, and because it doesn’t require modification of app code, sampling can often be used on a live process without the need for a restart before and after profiling, so can often be a good option for apps in production.

The effect of all of this on timing measurements if you’ve opted for sampling rather than instrumentation profiling is that the choice of wall clock time or CPU time becomes irrelevant. This is because whilst your profiler knows the call stack for each thread in every sample, it probably won’t know whether or not the thread was running (i.e., it could have been sleeping, suspended, etc.) – figuring this out could introduce unacceptable overhead whilst collecting data. As a result you’ll always be looking at wall clock time with sampling, rather than have the choice as you do with instrumentation.

Hopefully you’re now equipped to better understand and use the different kinds of timing data your performance profiler will show you. Please do feel free to chime in with questions or comments below – feedback is always much appreciated and if you need help I’d love to hear from you.

*Optimising SQL is beyond the scope of this post but I will cover it, using a similar example, in the future. For now I want to focus on the different timing metrics and what they mean to help you understand how to get the best out of your performance profiler. That being said, your tool might give you a handy hint so it’s not even as if you need to do that much thinking for yourself (but you’ll still look whip sharp in front of your colleagues)…

ANTS Performance Profiler hinting that the problem may be SQL-related.

Just don’t let them get a good look at your screen!

Live Bookmarking in ANTS Performance Profiler: a killer feature to help you zero in on performance problems fast

Last week I was sat with Simon, one of my client’s managers, as he showed me around their new customer support centre web app highlighting slow-loading pages. Simon, along with a couple of others, has been playing guinea pig using the new support centre in his day to day work.

The main rollout is in a few weeks but the performance problems have to be fixed first so support team members don’t spend a lot more time on calls, forcing customers to wait longer on hold before speaking to someone. Potentially bad for costs, customer satisfaction, and team morale!

Simon gave me a list of about a dozen trouble spots and I remoted into their production box to profile them all. I had to collect the results and get off as quickly as possible to avoid too much disruption; I could analyse them later on my own laptop. This gave me plenty of time to hunt down problems and suggest fixes.

I used Red Gate’s ANTS Performance Profiler throughout. One of the many helpful features it includes is bookmarking. You can mark any arbitrary time period in your performance session, give it a meaningful name (absolutely invaluable!), and use that as a shortcut to come back to it later.

For example, here I’ve selected the “Smart search” bookmark I created whilst profiling the support centre:

Timeline with bookmarked region selected.

The call tree shows me the call stacks that executed during the bookmarked time period. Towards the bottom you can see that SQL queries are using the vast majority of time in this particular stack trace:

Call tree showing call stacks within bookmarked region on timeline.

(Identifying SQL as a problem I took these queries and analysed them in more detail using both their execution plans, and SQL Server’s own SQL Profiler. I then suggested more efficient queries that could be used by NHibernate via repository methods.)

Also note we’re looking at Wall-clock time as opposed to CPU time. I won’t talk about the differences in detail here. What you need to understand is that Wall-clock time represents actual elapsed time. This matters because the queries execute in SQL Server, outside the IIS worker process running the site. Under CPU time measurements, which only include time spent in-process, they therefore wouldn’t appear as significant contributors to overall execution time.

Back on point: bookmarking is great as far as it goes, but you have to click and drag on the timeline after the fact to create them yourself. In the midst of an involved profiling session this is a hassle and can be error prone: what if by mistake you don’t drag out the full region you need to analyse? All too easily done, and as a result you can miss something important in your subsequent analysis.

Step in Live Bookmarks.

Basically, whilst profiling, you hit a button to start the bookmark, do whatever you need to do in your app, then hit a button to save the bookmark. Then you repeat this process as many times as you need. No worries about missing anything.

Here’s how it goes in detail:

  1. Start up a profiling session in ANTS Performance Profiler.
  1. Whilst profiling, click Start Bookmark. (To the right of the timeline.)

Start a live bookmark.

  1. Perform some action in your app – in my case I was clicking links to navigate problem pages, populate data, etc.
  1. Click Stop Bookmark.

Stop (and save) a live bookmark.

  1. The bookmark is added to the list on the right hand side of the timeline. It’s generally a good idea to give your bookmark a meaningful name. To do this just click the pencil icon next on the bookmark and type in the new name.

Rename bookmark.

  1. Rinse and repeat as many times as you need.
  1. When you’ve finished, click Stop in the top-left corner of the timeline to stop profiling.

Stop profiling.

It’s a good idea to save your results for later using File > Save Profiler Results, just in case the worst happens, and of course you can analyse them offline whenever you have time.

And that’s it: nice and easy, and very helpful when it comes to in depth performance analysis across a broad range of functionality within your application.

Any questions/comments, please do post below, or feel free to get in touch with me directly.

How to take a screenshot of your iPhone or iPad in iOS 7

Taking a screenshot/screengrab of your phone in iOS 7 is really easy, and it works in all apps. Just follow these simple steps.

  1. Press and hold the Power/Sleep button (see image below).
  2. Click the Home button (see image below).
  3. Release the Power/Sleep button.

Location of iPhone 5S Power/Sleep and Home buttons.

(Note: it also works the other way around: press and hold Home and then click Power/Sleep. Use whichever you prefer.)

If it works the screen should flash briefly to indicate that a screenshot has been taken. If your iPhone isn’t on silent you’ll also hear the camera shutter sound. Make sure you don’t hold Power/Sleep for too long or you’ll switch your iDevice off!

Your screenshot will be saved to the camera role so open up the Photos app to take a look at it. You can see here that I’ve taken several screen grabs today:

Screenshots in Photos app.

Been getting screenshot snap-happy today.

Tap on the screengrab you’ve just taken to view it full size.

Viewing individual screenshot in Photos app.

Looking at an individual screenshot: note the sharing button in the bottom-left corner.

You can get to sharing options by tapping the button in the bottom left corner (the one that looks like a square with an arrow pointing upwards out of it).

Sharing options for screenshot in Photos app.

Here I can share the screenshot or, more likely, send it to myself.

From here you can share the photo or send it to specific people via MMS or email. Just tap the appropriate icon and iOS will walk you through the rest.

The iOS 7 Keyboard: Un-Damn Your AutoCorrect

I used to suspect that most of the posts on damnyouautocorrect.com were faked. That was until last month, when I finally upgraded my aged iPhone 3GS to an iPhone 5S and, with it, iOS7.

Overall, it’s been a great experience, but the autocorrect… oh, how I hated the autocorrect. Every time I wrote an email, replied to an SMS, I felt like I was fighting with it. It would even correct correctly spelled words. For example, “were” became “we’re” and, with a bizarre nod to either Shakespeare or Schiller, “passcode” became “pass ode”.

Really annoying.

I don’t know if this is because iOS 7’s autocorrect different from iOS 5’s. Maybe it was just the cumulative effect of 4 years of typos combined with that putatively tweaked algorithm. Whatever, it become intolerable.

Fortunately there is some relief to be had with a bit of tweaking. Let’s take a look at the options, starting with the least intrusive and working our way up from there.

Option 1 – The Nutcracker: teach the dictionary one word at a time

Next time you enter a word that it wants to wrongly auto-correct and the suggestion pops up, hit the little X you can see on the right of the suggestion:

Incorrect suggestion when writing an SMS.

Dammit, no! “Were” is a completely valid word.

OK, now delete the word and try to type it in again. When the suggestion pops up again, hit the X to dismiss it. Now delete the word and enter it again, etc. Keep doing this until the incorrect suggestions stops appearing: it’ll probably take about 5 attempts. Once that happens it should mean the dictionary has forgotten the old correction and will instead use the word you’ve entered as the new correction in future, if it makes any suggestion at all.

That’s fine, obviously, but if it’s wrongly correcting loads of words this process could become quite arduous. Which brings us round to…

Option 2 – The Sledgehammer: reset the keyboard dictionary

For me the situation was so bad I had to go down this route. Before you follow me though, understand that there is a downside. Resetting the dictionary will remove all the words it’s learned from you, so it’ll have to learn them all over again. Whilst it’s doing that it’ll probably suggest all manner of humorous and possible highly inappropriate or career-limiting alternatives.

(Just thought I should warn you.)

To reset your keyboard dictionary, open up Settings, and then drill down to General > Reset. Now tap Reset Keyboard Dictionary.

Settings page for resetting various aspects of iOS.

Reset your keyboard dictionary from here.

You’ll be asked to enter your unlock passcode:

Reset keyboard dictionary passcode confirmation screen.

Enter your normal unlock passcode here.

Once you’ve done that you’ll be asked to confirm that you want to reset the dictionary (with a warning about losing all your custom words, as I mentioned):

Reset keyboard dictionary final confirmation.

No going back after this.

And you’re done.

You might still find the vanilla dictionary a bit annoying to start off with, but at least now you have a clean slate. You should find it suggesting a lot fewer spurious autocorrections.

But, if this still doesn’t satisfy you, there’s always… 

Option 3 – Nuke autocorrect from orbit: it’s the only way to be sure

It’s a bit extreme, but you can just disable autocorrect, and it’ll never bother you again.

You need to do this via the keyboard settings, which you’ll find in Settings > General > Keyboard. They look like this:

Keyboard settings.

If you can’t find joy any other way, these settings give you access to the thermonuclear option.

You just need to switch off Auto-Correction. If it annoys you, you can also switch off Auto-Capitalization.

It’s also worth checking your shortcuts to make sure none of them is causing any annoying autocorrections.

Note: the Check Spelling setting is nothing to do with autocorrect. All it does is highlight what it thinks are misspelled words when it’s switched on. It does not try to correct them for you.

Final Thoughts

Things have definitely been better since I reset the keyboard dictionary, but there’s still the odd noticeable difference in iOS 7 autocorrect behaviour as compared to previous versions. For me the most noticeable is that in general it seems to suggest corrections/autocompletions much less often than did previous versions. This is sort of OK but it does mean you feel like you’re having to type a lot more.

Another comment I’d make is that with the form factor of the iPhone 5/5C/5S being longer and thinner than the 3GS and 4/4S, I don’t think Apple’s vanilla keyboard works quite as well because you have to stretch further to hit the keys in the centre. For me, at any rate, this seems to result in a few more typos.

There’s a lot of innovation around mobile and tablet on-screen keyboard design on both Android and Windows 8.1/Windows Phone 8. A good chunk of this is from third parties. Unfortunately this isn’t an option with iOS. I can see why Apple would be unwilling to open up the keyboard implementation to third parties, but it would be good to see them revisit it.

Hope this has been useful for you! And please let me know if you’re aware of anything else that might help.