Last active
August 29, 2015 14:21
-
-
Save norio-nomura/d9ec7212f2cfde3fb662 to your computer and use it in GitHub Desktop.
Test recursion on Himotoki
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
MacBook Pro (Retina, 13-inch, Late 2013) 2.6 GHz Intel Core i5
before: 0.76 sec
after: 0.11 sec