## A “shortcut” for multiplying any two numbers

I ran into something interesting when working last night that wasn’t immediately obvious to me at first. It’s an alternate way to calculate the product of any two numbers.

I first noticed something was going on when I squared a number and then compared it to the product of numbers on either side of the original number:

```5 * 5 = 25
6 * 4 = 24 (1 from 25)
7 * 3 = 21 (3 from 24)
8 * 2 = 16 (5 from 21)
9 * 1 = 9  (7 from 16)
```

If you subtract each result from the one before it, you see the series: 1, 3, 5, 7. “That’s interesting, I’m increasing the distance between the two numbers, and the result keeps changing by 2 also, I wonder if there’s something to that. Maybe I just got lucky, and this is something odd about 5*5 in particular. So I tried the same process, but started with 6*6, or 8*8 and got the same result.

Next, instead of looking at the difference in values from the product before it, I decided to check what the value would be compared to the original square of their average.

```5 * 5 = 25 (the average, base case)
6 * 4 = 24 (1 from average)
7 * 3 = 21 (4 from average)
8 * 2 = 16 (9 from average)
9 * 1 = 9 (16 from average)
```

Now that’s interesting! The result of two seemingly unrelated numbers, 7 and 3 for instance, is a perfect square away from the square of the two numbers’ average.

So at this point, I have the theory that:

```x * y = average(x,y)^2 - someOtherSquareRelatedTo(x,y)
```

Looking at the 8*2 example, i notice that they’re 9 away from 25, or 32. The average of 8 and 2 is 5, so both 8 and 2 are a distance of 3 away from 5. So that’d give the formula:

```x * y = average(x,y)^2 - (average(x,y) - min(x,y))^2
```

If I expanded that out, then that’d result in:

```x * y = average(x,y)^2 -
(average(x,y)^2 - 2*average(x,y)*min(x,y) + min(x,y)^2)
```

which simplifies to:

```x * y = 2*average(x,y)*min(x,y) - min(x,y)^2
```

That looks just crazy to me. Maybe I’m missing something, but that’s just not obvious to me at all when I think about arbitrary x and y. I set up a script here just to double check and run the numbers, and sure enough it works out. Even for fractions and negative x and/or y.

Did I miss this lesson in school? I feel proud that I’ve figured this out, and usually when I feel like this it means I’ve missed something super obvious :D.

## Great talks and coffee at AltConf

Lots of really great stuff at AltConf this year. I wasn’t lucky enough to get a raffled badge for WWDC, but I’m very glad I was still able to come and hang out at AltConf and meet some new people. Already, this week has been a huge inspiration to get Loose Leaf done and shipped. Being surrounded by folks who are churning on really cool projects rubs off on you. This year, AltConf is hosting its lab sessions at its 2nd location, and it’s been great to spend some time each afternoon coding hard and combing through all the Apple announcements in a crowded room of other folks doing the same thing: like we’re all racing to know all the things.

Besides coding and the labs, I’ve really enjoyed the talks. Two in particular I’ll link to here, but all of the ones I’ve been to have been awesome. Sofia Dvoynos gave a great talk about marketing apps. All the usual suspects were mentioned: planning, email campaigns, keywords, etc, but what set this apart and really helped me out was the concrete examples and references to help get all that done. Everyone knows competitive analysis is important, but she was good enough to link to the xls she uses to research and compare – awesome stuff. Watch her talk below:

Sofia Dvoynos: From Zero to Marketing in 7 days

Also great was Carla White’s inspirational talk. She gave a refreshing talk about how to truly make your app better, and that’s to make sure to take time for the things that matter: being purposefully and specifically grateful of others and giving back however you can. It’s more than I’ll summarize in a small paragraph, please do take the ~30m and watch it.

Outside the conference, I’ve also made some good headway on a personal goal: drink as much good coffee as I can! So far I’ve visited Chrome, Blue Bottle, and Workshop Cafe, and I expect to visit many more shops throughout the week. All in all a fun week! I highly recommend watching the AltConf speakers presentations here: http://www.altconf.com/speakers/ – lots of good stuff going on.

## Tracking IOKit Dirty Memory in iOS using Instruments

I’ve been spending the past week of Loose Leaf development tracking where and how my app’s memory is allocated at run time. My goal is to send all of my memory stats to MixPanel with every event I track. During beta and after launch, all of this information will help me to better understand how people are using the app.

This’ll be especially helpful if/when I get memory crash reports – tracking down which iPad models are having the hardest time, and being able to use MixPanel to see how Loose Leaf is allocating memory on those iPad models – is it OpenGL textures? Vertex buffers? UIImages? Core Animation?

Knowing how the app’s caches are performing, where memory is allocated, and why it’s allocated is going to be a huge help to further optimize performance after launch.

My end goal is to have similar memory allocation numbers at runtime that the Allocations tool in Instruments gives me when profiling. So far, I have the following debug screenshot that shows how and where memory is allocated in the app. The important numbers from the screenshot are the 28.6Mb of memory in the MMLoadImageCache (these are UIImages), and the 101Mb in the MMPageCacheManager (this is largely OpenGL, including the Textures and VBOs later in the screenshot). These sum to roughly 130Mb of actively allocated and used memory.

I also have a few views that rely on drawRect:, and those views have their backing store created by Core Graphics. All this together can account for the 167Mb of memory that Instruments shows me in the Allocations instrument.

What’s going on with that 392 Mb of dirty memory?! Yikes, this number is over double my allocations and is absolutely terrifying. After some research, I found this post about Finding iOS Memory, which mentions that OpenGL’s textures are shown Dirty memory labelled as IOKit. Sure enough, i see lots of IOKit memory when I look at dirty memory:

This makes me worry that perhaps I’m not cleaning up old textures properly, and I’m somehow leaving my memory allocated in OpenGL after I’m finished with a texture. Looking through my code, I’ve confirmed I’m calling “glDeleteTextures(1, &textureID);” for my texture IDs like I should – so what could the problem be?

Then I found this answer on StackExchange, which mentions:

Some drivers may keep the storage allocated so that they can reuse it for satisfying future allocations (rather than having to allocate new storage – a common misunderstanding this behaviour leads to is people thinking they have a memory leak), other drivers may not.

If that’s true, then that’d mean that I have done my job and properly released that memory, and OpenGL is just optimizing when it actually frees that memory back to the system.

To test this out, i background my application and open up Pages, Keynote, and Numbers in an attempt to force a Low Memory Warning on the system. Instruments shows these memory events being triggered while my app is in the background, and more importantly it shows the dirty memory falling back into line with my current allocations. When I return to my appÂ after opening a few apps and browsing around outside my app, Instruments now shows dirty memory much closer to my current allocations:

Moral of the story: Keep a close eye on allocations and dirty memory, and make sure you know why and when your memory is marked as dirty. It turned out that Loose Leaf is doing a good job cleaning up its old unused OpenGL textures, but OpenGL is just slow when it deallocs that memory. I may try to do a better job loading new textures into old texture’s memory and purposefully re-using memory instead of always allocating new, but I’m glad to see that I didn’t have a massive leak after all.