Tuesday, May 20, 2014

NGINX + PostgreSQL + PostGIS - performance baseline/diff

Just wanted to share some of the initial benchmark from http_load on the project I'm working right now. Why the excitement? I've been an MS oriented guy for the last 20 years and moving away from IIS and MSSQL (where you can be waiting 20-30 seconds for the initial IIS/.NET/SQL app startup) to NGINX with PostgreSQL stack is life changing - no exaggeration!

So here is what I got on Digital Ocean lowest spec machine (1 core, 20GB SSD, 512 MB RAM, Ubuntu 12) with a bare NGINX:

34178 fetches, 10 max parallel, 683560 bytes, in 5 seconds
20 mean bytes/connection
6835.6 fetches/sec, 136712 bytes/sec
msecs/connect: 0.0445469 mean, 0.937 max, 0.021 min
msecs/first-response: 1.41242 mean, 101.975 max, 0.257 min

And with the full nginx->postgresql with postgis searching for speed limits around submitted location (but only a few limits present in db for a moment):

5574 fetches, 10 max parallel, 6.22058e+06 bytes, in 5 seconds
1116 mean bytes/connection
1114.8 fetches/sec, 1.24412e+06 bytes/sec
msecs/connect: 0.0561055 mean, 0.37 max, 0.023 min
msecs/first-response: 8.68285 mean, 187.733 max, 0.812 min

So it got from almost 7k to 1k per second, still that's from the different universe compared to what IIS/.NET would do for me, and look at the machine spec! Plus, $0.0 for nginx + $0.0 for posgre/postgis - pure win!

-- Stan.

Friday, November 29, 2013

Apple MKMapView vs. Google iOS SDK map - CPU, compass image, center and rotate.

Why I didn't use native Apple's map a year ago when I was going through the options for my apps?

I was looking for the "live" map that would be able to follow your location, option to rotate so your heading can be always on top of the map and while it rotates it should rotate street names gracefully so they are not shown upside down.

Should I tell Apple maps for iOS6 failed miserably for all of those requirements. So I used Google's alternative. It gave me great rotation, street names handling and nothing to complain about.




Watching iOS7 location videos made me really intrigued, it looked like "oh, Apple fixed it all and brought us the map that can rotate correctly". I was really keen to try and after two months of fixing my apps for iOS7 and releasing them I finally got to try.... And I'm not sure this is it.

Why?

You basically have an option to either center the map yourself or set it up to track by itself:


[self.map setUserTrackingMode:[MKUserTrackingModeFollow|MKUserTrackingModeFollowWithHeading] animated:[true|false]

Well, there are few problems here. 

Rotate and center sync. If you want to rotate with one of the automated tracking options, you'd probably need to sync your rotation with the user location tracking animation. Otherwise, for my naive and short attempts the rotation and auto-tracking create weird effect of user location floating around its center. I didn't follow the path of trying to sync that yet and will see if this is worth an effort.

Compass image. Small extra annoying factor here is that once you rotate the map (set the map camera heading) to something not equal zero, the "compass" thingy appears in the right upper corner:



My first thought was - "oh, I'l move this thingy where I want or disable it for iPad version as I show heading elsewhere". Let me do a read up, let me google for it, let me study Apple's forum for it... What? I can't do it! I love Apple for things that were decided for us, it is part of their spirit and I'm glad they keep it even stronger now than before!

This compass thingy is not a big issue I can move my star button (that happened to be in this place by accident) - I'm not that picky.

It has glitches. From time to time it looks like map zoom is being reset for a moment and than re-established again. I can't really correlate it to whatever I'm doing (as I'm doing nothing but set camera's heading and I do for every location change while zoom "blink" only happens once in a longer while). And the first time I rotate it it goes through the field of black and white rectangular and then does it from time to time, probably when tiles has not been loaded yet for some area I suddenly need to expose by programmatic rotation. This never happens to the Google map.
+ When changing programmatically (or by setting the auto option with WithHeading) heading from 360 to 1, Apple's map rotates -360 + 1 degree. Like, this can't be true? I'm probably just silly. But Google does it right, and it makes me feel less silly and more desperate.
+ Compass image shows even when I have enableRotate to NO, but when phone points exactly to 0 heading, the compass image disappears. So when my user will drive exactly in North direction they know it by not seeing the image?! Very consistent!

I can center and rotate all by myself.

I'm a big boy, if I proved it with Google maps I can prove it everywhere?

Ok. I'm loosing that extra smooth animation for centering the map should I tell. But it just looks as it does for the Google maps, that would suffice. Seems to work just ok. So I was sitting and looking at that center and rotate I put together thinking "Stan, you are a genius, you proved it!".

As I tend to spend few minutes in this state, I felt how my lap is getting hotter, and hotter .... Oh oh, this is my beloved temperature based CPU profiling instrument! 

So here is the reason of why I'll be thinking twice now if I should use native Apple's map for the live map option, let me provide it here. On the top you'll see Apple's map consumption while centering and rotating and below it you'll see the same task executed by a Google map. If simulators doe this to my mac, I guess I can speculate the same CPU/battery consumption ratio will stay on real devices:


My story ends here, enough for this evening, I need to re-group, re-think, re-try, re-study ....








Sunday, September 29, 2013

iOS 7 vs iOS 6 memory consumption. OMG?

Known thing my app starts slower on iPhone 4 with iOS7 then it is on the same iPhone 4 with iOS6. This is pretty sad, but not the only sad thing...

As I'm profiling now the app before its soon to come release to AppStore, I got to the following screenshots for the fresh app start on iPhone 4 with iOS6:


Note the 1.55MB number. And now, the sad thing, same fresh start on iPhone5 with iOS7:


Noticed that 8.21MB?! I currently only have iOS7 installed on iPhone 5, so I can't compare iPhone 4 iOS7 vs iOS6 consumption, but I believe this iPhone 5/4 factor should not play any role here. It is just iOS thingy. 

While not that sad for iPhone 5/5s, it is pretty bad news for my users that are still on iPhone 4, apps are going to consume more. All apps, not only mine... App startup is becoming definitely heavier and those extra allocations in iOS7 are surely standing for more work done by iOS7 while starting the app.

Having read Steve's biography, it looks to me like a step away from the "saving lives" approach to plain MS's "throw more memory on it - problem solved".

May I be wrong? I hope!

Yours,
Stan.

Thursday, May 2, 2013

A very short note on migrating from Spring.NET 1.1.x to 1.3.x or 2.x

I used to have something like this in my code for getting the Spring.NET context:

using (IApplicationContext ctx = ContextRegistry.GetContext())
            {
                
                traceListener =
                    (TraceListener) ctx.GetObject(initializationData);
            }

After upgrade to 1.3.2 I was rewarded with:

No context registered under name '{0}'. Use the 'RegisterContext' method or the 'spring/context' section from your configuration file.

Short investigation showed Spring.NET is not then getting the context initiated again if it was removed (I didn’t realize that) by using/Dispose pattern.

I’ll let it to the conscious of spring.NET authors to decide if this is a correct implementation of disposal pattern from their side, corrected line of code now looks just like:

traceListener =
                    (TraceListener) ctx.GetObject(initializationData);

Monday, April 15, 2013

Sqllite - Month and Year from unixepoch column

Just wanted to share how to get month and year from sqllite column that keeps unixepoch numeric value. Without further ado, here is a sample:

SELECT cast(strftime('%m', datetime(start, 'unixepoch')) as integer) as month, cast(strftime('%Y', datetime(start, 'unixepoch')) as integer) as year, * FROM track where month=4

Here is what results look like:

image

What about null values?

After nullifying end value, and running the following query:

SELECT cast(strftime('%m', datetime(end, 'unixepoch')) as integer) as month, cast(strftime('%Y', datetime(end, 'unixepoch')) as integer) as year, * FROM track
the result is:

image

What about zeroes in the source column? Here is the result:

image

What is my take away from all that? From my design perspective I definitely don’t want to have some fields for dates that would be NOT NULL DEFAULT(0), I better have them nullable with null value representing a missing date, not a 0.

Official sqlite date and time functions page

Friday, December 7, 2012

The state of technical blogging - my 5 cents

I know I have not been blogging here for some time already. But... same is valid for my friends and ALL of those guys I have in my blog roll and rss subscription. Individuals ... It is a bit sad to see how that content aggregation is taking over. Stackoverflow, Ray Wenderlich etc, content aggregation is a current way to rule the technical information delivery it seems.

For myself, I'm missing my friends and those independent bloggers sharing their raw thoughts and being authors instead of competing for points on those super sites. It is sad for me hearing how those 100k+ points on stackoverflow make you a celebrity. I hope one day I see as many new entries in my rss subscriptions as there used to be 3 years ago, when this blogging stuff was novel and everyone could blog his heart out.

When it comes to stackoverflow, I have that feeling of stagnation already over those rules and big brother style of those 100k+ guys bullying/editing novices. Some kind of artificial new elite editing and voting down everybody else's entries.

I'd like to believe into the next level of content aggregation to be brought by Google based onto individual bloggers entries, not rated/edited by any snob 100k+ reputation guys but live comments and feedback of readers. I feel like stackoverflow filled the gap at some point, but this is it. There is something rotten in that style of aggregation, and its smelling worse and worse I believe...

Let's see what's next, but I hope that future where my friends are blogging again as they were 3 years ago will come...

Sunday, October 14, 2012

UX, UX, UX and bad reviews in AppStore

I got that really bad review in UK's AppStore:


did not work at all save your money 
did not work at all sent two text for help but no replies so save your money John H


First, I felt quite lost. "That can't be true!" I was telling myself. I respond to all of my users within 30 minutes when I don't sleep and it might take ~8 hours when it is night by Central European Time. 

There is a certain UX problem I currently have with my app that every 100th customer understands the fact I don't show the speed in my speedometer when there is no GPS lock as app malfunction. There is a GPS indicator showing red and reading OFF when there is no signal, but still, I've started to fix it.

When I reread once again, the part "sent two text for help but no replies" rang my bell quite a bit! I have following options in my app:


So the user tapped on S.O.S, ignored the header "Sent my location", saw the sms window open with his location to share and tried to send it out. I have no idea what phone number he sent that location info to. He obviously tried it twice, getting more frustrated each time, which resulted in that 1* review.

Lesson taken! I'm now changing that S.O.S to "Share my location" and "Feedback" to "Feedback & Support":



A big lesson for me again. I already learnt with my first UX problem that whatever can be misinterpreted by user, will be misinterpreted.

I only have wished it would not take another 10 days to get the updated version into AppStore :). 

Here is free version on my speedo, if you want to judge for yourself :) :