Skip to content

Instantly share code, notes, and snippets.

@norio-nomura
Last active August 29, 2015 14:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save norio-nomura/d9ec7212f2cfde3fb662 to your computer and use it in GitHub Desktop.
Save norio-nomura/d9ec7212f2cfde3fb662 to your computer and use it in GitHub Desktop.
Test recursion on Himotoki
import Foundation
import XCTest
import Himotoki
class PerformanceTests: XCTestCase {
func testRecursion() {
let JSON = deepNestedJSON(0)
self.measureBlock {
var t: Test? = decode(JSON!)
XCTAssert(t?.depth == Test.depth)
}
}
}
// copy from https://github.com/robrix/Prelude/blob/master/Prelude%2FFix.swift
func fix<T, U>(f: (T -> U) -> T -> U) -> T -> U {
return { f(fix(f))($0) }
}
let deepNestedJSON: Int -> [String: AnyObject]? = fix { recur in
return { n in
if n <= Test.depth {
if let r = recur( n + 1 ) {
return [
"a": r,
"depth": NSNumber(integer: n)
]
} else {
return ["depth": NSNumber(integer: n)]
}
} else {
return nil
}
}
}
struct Test: Decodable {
static let depth = 5000
let depth: Int
static func decode(e: Extractor) -> Test? {
let key = reduce(1..<depth, "a", {n,_ in return n + ".a" }) + ".depth"
let create = { Test(depth: $0) }
return build(
e <| key
).map(create)
}
}
---
Himotoki/Extractor.swift | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/Himotoki/Extractor.swift b/Himotoki/Extractor.swift
index c9b2c8b..33856c0 100644
--- a/Himotoki/Extractor.swift
+++ b/Himotoki/Extractor.swift
@@ -15,7 +15,7 @@ public final class Extractor {
private func rawValue(key: String) -> AnyObject? {
if let dictionary = rawValue as? [String: AnyObject] {
- return valueFor(key.componentsSeparatedByString("."), dictionary)
+ return valueFor(ArraySlice(split(key) {$0 == "."}), dictionary)
} else {
return nil
}
@@ -52,18 +52,18 @@ public final class Extractor {
}
// Implement it as a tail recursive function.
-private func valueFor(keyPathComponents: [String], dictionary: [String: AnyObject]) -> AnyObject? {
- if keyPathComponents.isEmpty {
+private func valueFor(keyPathComponents: ArraySlice<String>, dictionary: [String: AnyObject]) -> AnyObject? {
+ if isEmpty(keyPathComponents) {
return nil
}
- if let object: AnyObject = dictionary[keyPathComponents.first!] {
+ if let object: AnyObject = dictionary[first(keyPathComponents)!] {
switch object {
case is NSNull:
return nil
- case let dict as [String: AnyObject] where keyPathComponents.count > 1:
- let tail = Array(keyPathComponents[1..<keyPathComponents.count])
+ case let dict as [String: AnyObject] where count(keyPathComponents) > 1:
+ let tail = dropFirst(keyPathComponents)
return valueFor(tail, dict)
default:
--
2.3.2 (Apple Git-55)
@norio-nomura
Copy link
Author

MacBook Pro (Retina, 13-inch, Late 2013) 2.6 GHz Intel Core i5
before: 0.76 sec
after: 0.11 sec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment