Archive for August 25, 2016

Thursday, August 25, 2016

Foundation Hashing

Paul Haddad:

TIL NSData only uses the first 80 bytes to hash itself and doesn’t use length at all for some reason.

Other classes with potentially bad hash codes: NSArray and NSDictionary both simply return their count. NSString’s hashing has changed a few times. Currently it uses up to 96 characters (taken from the beginning, middle, and end) and also incorporates the length.

If you know these hash functions are bad for your data, you can use wrapper objects to override the -hash method or an NSMapTable with a custom NSPointerFunctions.

Previously: Swift Tuples Aren’t Equatable.

Update (2016-08-25): David Smith:

Using the length is a good idea. We [should] change that.

Just an oversight afaik. Not all that many people hitting that code path. Should be a safe fix.

Dropbox Document Scanning Tech

Ying Xiong:

A few weeks ago, Dropbox launched a set of new productivity tools including document scanning on iOS. This new feature allows users to scan documents with their smartphone camera and store those scans directly in their Dropbox. The feature automatically detects the document in the frame, extracts it from the background, fits it to a rectangular shape, removes shadows and adjusts the contrast, and finally saves it to a PDF file. For Dropbox Business users, we also run Optical Character Recognition (OCR) to recognize the text in the document for search and copy-pasting.


We decided to develop a customized computer vision algorithm that relies on a series of well-studied fundamental components, rather than the “black box” of machine learning algorithms such as DNNs. The advantages of this approach are that it is easier to understand and debug, needs much less labeled training data, runs very fast and uses less memory at run time. It is also more accurate than Apple’s SDK for the kinds of usage scenarios we care about; in an A/B test evaluation, the detections found by our algorithm are 60% less likely to be manually corrected by users than those found by Apple’s API.

Jongmin Baek:

Once we have a rectangular rendering of the document, the next step is to give it a clean and crisp scanned appearance. We can explicitly formulate this as an optimization problem; that is, we solve for the final output image J(x,y) as a function of the input image I(x, y) that satisfies the two aforementioned requirements to the greatest extent possible:
  • The background of the document is mostly a uniform white, with even illumination.
  • The foreground text and figures are crisp and visible with high contrast.


In our experiments, the output colors using this simple algorithm would look faded, even though the RGB values were exactly the same as the input! The reason is that the human visual system is based on relative brightness, not absolute ones; this makes colors “pop” more relative to the dull gray of the input, but not relative to the bright white background of the enhanced image.

.NET/C# Generics History

Don Syme (via Doug Gregor):

Generics for .NET and C# in their current form almost didn’t happen: it was a very close call, and the feature almost didn’t make the cut for Whidbey (Visual Studio 2005). Features such as running CLR code on the database were given higher priority.

It was only through the total dedication of Microsoft Research, Cambridge during 1998-2004, to doing a complete, high quality implementation in both the CLR (including NGEN, debugging, JIT, AppDomains, concurrent loading and many other aspects), and the C# compiler, that the project proceeded. Product group resourcing for the feature was low until 2004, and remained sparse, leading to major overload on MSR Cambridge employees, though ultimately the code, designs and specifications were fully transferred into both the CLR and C#. Today, the future of the CLR is firmly in the hands of those in Redmond.


What would the cost of inaction have been? What would the cost of failure have been? No generics in C# 2.0? No LINQ in C# 3.0? No TPL in C# 4.0? No Async in C# 5.0? No F#? Ultimately, an erasure model of generics would have been adopted, as for Java, since the CLR team would never have pursued a in-the-VM generics design without external help.