diff --git a/public/_data.json b/public/_data.json
index 10343ac..5c1d7cd 100644
--- a/public/_data.json
+++ b/public/_data.json
@@ -20,7 +20,18 @@
},
"posts": [
{
- "title": "A git pre-commit hook for iOS",
+ "title": "Easy Optimization Wins",
+ "date": "10th August, 2016",
+ "timestamp": 1470850249,
+ "tags": [
+ "ios",
+ "git"
+ ],
+ "author": "Sami Samhuri",
+ "url": "/posts/2016/08/easy-optimization-wins"
+ },
+ {
+ "title": "A Git Pre-commit Hook for iOS",
"date": "4th August, 2016",
"timestamp": 1470328683,
"tags": [
@@ -116,17 +127,6 @@
"author": "Sami Samhuri",
"url": "/posts/2015/06/debugging-layouts-with-recursive-view-descriptions-in-xcode",
"link": "http://jeffreysambells.com/2013/01/24/debugging-layouts-with-recursive-view-descriptions-in-xcode"
- },
- {
- "title": "→ The Unofficial Guide to xcconfig files",
- "date": "1st June, 2015",
- "timestamp": 1433171811,
- "tags": [
-
- ],
- "author": "Sami Samhuri",
- "url": "/posts/2015/06/the-unofficial-guide-to-xcconfig-files",
- "link": "http://pewpewthespells.com/blog/xcconfig_guide.html?utm_campaign=iOS%2BDev%2BWeekly&utm_source=iOS_Dev_Weekly_Issue_200"
}
]
}
\ No newline at end of file
diff --git a/public/posts/2016/08/_data.json b/public/posts/2016/08/_data.json
index 42c893f..6b2ac83 100644
--- a/public/posts/2016/08/_data.json
+++ b/public/posts/2016/08/_data.json
@@ -2,7 +2,7 @@
"ios-git-pre-commit-hook": {
"id": "ios-git-pre-commit-hook",
"author": "Sami Samhuri",
- "title": "A git pre-commit hook for iOS",
+ "title": "A Git Pre-commit Hook for iOS",
"date": "4th August, 2016",
"timestamp": 1470328683,
"link": null,
@@ -11,5 +11,18 @@
"ios",
"git"
]
+ },
+ "easy-optimization-wins": {
+ "id": "easy-optimization-wins",
+ "author": "Sami Samhuri",
+ "title": "Easy Optimization Wins",
+ "date": "10th August, 2016",
+ "timestamp": 1470850249,
+ "link": null,
+ "url": "/posts/2016/08/easy-optimization-wins",
+ "tags": [
+ "ios",
+ "git"
+ ]
}
}
\ No newline at end of file
diff --git a/public/posts/2016/08/easy-optimization-wins.md b/public/posts/2016/08/easy-optimization-wins.md
new file mode 100644
index 0000000..78ead5c
--- /dev/null
+++ b/public/posts/2016/08/easy-optimization-wins.md
@@ -0,0 +1,47 @@
+It's not hard to hide a whole lot of complexity behind a function call, so you have to be very aware of what the functions you are using actually do, and how long they take to do it.
+
+Here's some example code illustrating a big performance problem I found in a codebase I've inherited. We have a dictionary keyed by a string representing a date, e.g. "2016-08-10", and where the values are arrays of videos for that given date. Due to some unimportant product details videos can actually appear in more than one of the array values. The goal is to get an array of all videos, sorted by date, and with no duplicates. So we need to discard duplicates when building the sorted array.
+
+```Swift
+func allVideosSortedByDate(allVideos: [String:[Video]]) -> [Video] {
+ var sortedVideos: [Video] = []
+ // sort keys newest first
+ var dateKeys = allVideos.allKeys.sort { $1 < $0 }
+ for key in dateKeys {
+ for video in allVideos[key] {
+ if !sortedVideos.contains(video) {
+ sortedVideos.append(video)
+ }
+ }
+ }
+ return sortedVideos
+}
+```
+
+Can you spot the problem here? `sortedVideos.contains(_:)` is an `O(n)` algorithm which means that in the worst case it has to look at every single element of the collection to check if it contains the given item. It potentially does `n` operations every time you call it.
+
+Because this is being called from within a loop that's already looping over all `n` items, that makes this an O(n2) algorithm, which is pretty terrible. If you ever write an n2 algorithm you should find a better solution ASAP. There almost always is one! If we have a modest collection of 1,000 videos that means we have to do 1,000,000 operations to get a sorted array of them. That's really bad. One measly line of innocuous looking code completely blew the performance of this function.
+
+In this particular case my first instinct is to reach for a set. We want a collection of all the videos and want to ensure that they're unique, and that's what sets are for. So what about sorting? Well we can build up the set of all videos, then sort that set, converting it to an array in the process. Sounds like a lot of work right? Is it really faster? Let's see what it looks like.
+
+```Swift
+func allVideosSortedByDate(allVideos: [String:[Video]]) -> [Video] {
+ var uniqueVideos: Set