Archive for December, 2011

Paintings @ Bright Lyons

Passed by Bright Lyons on Atlantic Avenue in Brooklyn and saw this awesomeness,

Bright Lyons, Homer and Bart

Batching, a basis for optimization

It’s interesting that in 3 distinct domains I’ve run across the same underlying basis for optimization:

  • Graphics: Modern GPUs depend heavily on batching primitives, typically triangles. Instead of rendering triangles individually, you get much better performance by batching primitives together in a list, sending it to the GPU via a single call, then letting the GPU pipelines to do their thing. Even before modern GPUs existed, graphics cards supported techniques like BitBlt which, essentially, performed operations on batched blocks of pixels, to take advantage of the embarrassingly parallel nature of computer graphics.
  • Relational Databases: Issuing lots of small queries can kill performance. A better strategy is, usually, to issue fewer queries, joining and returning as much data as possible with each query. Even if these queries becomes complex and costly, the cost of a complex query will usually still be less than the aggregate cost of numerous simpler queries.
  • Networking: The speed of light sucks… server and packet switching latencies make things worse. I usually assume ~50ms baseline latency to send a request packet + get a reply packet back from an internet server (I use the term “packet” loosely, referring to programmer-defined, application-level “packets” or messages, or whatever you like to call them, not necessarily TCP/IP packets). Note that this baseline is regardless of the amount of information in a packet and is bound by the travel time between server and client. So, to optimize communication and bandwidth, a good strategy is to transfer as much as possible per-packet instead of depending upon numerous requests/responses to/from a server, which would mean lots of packets and lots of wasted time.

Multi-faceted online identities

Incredibly insightful insights by Christopher Poole (“moot”, founder of 4chan and Canvas)

From SXSW earlier this year

Zuckerberg’s totally wrong on anonymity being total cowardice. Anonymity is authenticity. It allows you to share in an unvarnished, unfiltered, raw and real way.

The cost of failure is really high when you’re contributing as yourself, to fail in an environment where you’re contributing with your real name is costly.

As for how anonymity connects to identity, he spoke to this at Web 2.0

It’s not who you share with, it’s who you share as… We all have multiple identities, it’s part of being human, identity is prismatic. Google and Facebook would have you believe you are a mirror, but in fact we’re more like diamonds, you can look at people from any angle and see something totally different and yet they’re still the same

Showing the transit layer with the Google Maps API

While Google Maps has a very useful transit layer (showing subway lines, bus stops, etc.) available when zoomed in on a city, this layer is unfortunately not exposed via the Google Maps API. However, as demonstrated on BlinkTag Inc. by Brendan Nee, it’s possible to load the transit layer as a custom tile layers, pulling the transit layer images directly from Google’s servers.

// add transit overlay
var transitOptions = {
getTileUrl:
function (coord, zoom)
{
return "http://mt1.google.com/vt/lyrs=m@155076273,transit:comp|vm:&" + "hl=en&opts=r&s=Galil&z=" + zoom + "&x=" + coord.x + "&y=" + coord.y;
},

tileSize:
new google.maps.Size(256, 256),
isPng:
true
};

var transitMapType = new google.maps.ImageMapType(transitOptions);
map.overlayMapTypes.insertAt(0, transitMapType);    

Google Maps, Transit Layer, Subway - NYC, City Hall


However, there are 2 issues you may quickly notice:

1. Custom styling applied to the base layer is lost.
This is because full image tiles are loaded, which completely obscures the lower layer. A solution to this is to find and copy the apistyle and style URL parameters when the base layer is loaded (you can do this by looking at the GET requests with a tool like Firebug). You then simply add these paremeters to the URL returned by the getTileUrl() function.

getTileUrl: function (coord, zoom)
{
return "http://mt1.google.com/vt/lyrs=m@155076273,transit:comp|vm:&" + "hl=en&opts=r&s=Galil&z=" + zoom + "&x=" + coord.x + "&y=" + coord.y + "&apistyle=s.t%3A3%7Cp.h%3A%23C5C5C5%7Cp.s%3A-100%7Cp.l%3A37%7Cp.v%3Aon%2Cs.t%3A35%7Cp.h%3A%23F284FF%7Cp.s%3A100%7Cp.l%3A-9%7Cp.v%3Aon%2Cs.t%3A81%7Cp.v%3Aoff&s=Gal&style=api%7Csmartmaps";
},

Google Maps, Transit Layer, Subway - NYC, City Hall

2. The large subway stop markers are useless
In New York City at least, it’s impossible to identify train lines by color alone, so it’s fairly important to see the letter or number identifier for trains at the different stations. The map has both large and small markers for each station, but only the small markers shows this information. I couldn’t figure out a way to get the larger marker to show the letters/numbers, but by changing “vm:” to “vm:1” you can completely remove the large markers from the map. However, this also shrinks the size of the lines indicating the train routes.

getTileUrl: function (coord, zoom)
{
return "http://mt1.google.com/vt/lyrs=m@155076273,transit:comp|vm:1&" + "hl=en&opts=r&s=Galil&z=" + zoom + "&x=" + coord.x + "&y=" + coord.y + "&apistyle=s.t%3A3%7Cp.h%3A%23C5C5C5%7Cp.s%3A-100%7Cp.l%3A37%7Cp.v%3Aon%2Cs.t%3A35%7Cp.h%3A%23F284FF%7Cp.s%3A100%7Cp.l%3A-9%7Cp.v%3Aon%2Cs.t%3A81%7Cp.v%3Aoff&s=Gal&style=api%7Csmartmaps";
},

Google Maps, Transit Layer, Subway - NYC, City Hall

There is a third issue that’s pretty noticeable as well: bus stops do not how the identifier of the buses that stop at them. I’ve yet to find a way to show them.