binary-trees Swift #9 program
source code
// The Computer Language Benchmark Game
// https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
//
// contributed by Ralph Ganszky
// Swift binary-trees program should use ARC
// https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html
import Dispatch
import Foundation
import apr
let nullptr = OpaquePointer(bitPattern: UInt.max)!
struct Node {
var left: OpaquePointer
var right: OpaquePointer
func check() -> Int {
if left != nullptr {
let l = UnsafeMutablePointer<Node>(left)
let r = UnsafeMutablePointer<Node>(right)
return l[0].check() + r[0].check() + 1
} else {
return 1
}
}
}
func CreateTree(_ depth: Int, _ pool: OpaquePointer) -> OpaquePointer {
let nodePtr = OpaquePointer(apr_palloc(pool, MemoryLayout<Node>.stride))!
let node = UnsafeMutablePointer<Node>(nodePtr)
if depth > 0 {
node[0].left = CreateTree(depth-1, pool)
node[0].right = CreateTree(depth-1, pool)
} else {
node[0].left = nullptr
node[0].right = nullptr
}
return nodePtr
}
let minDepth = 4
let maxDepth: Int
if CommandLine.argc > 1 {
let arg = Int(CommandLine.arguments[1]) ?? 10
maxDepth = (arg > minDepth + 2) ? arg : minDepth + 2
} else {
maxDepth = 10
}
guard apr_pool_initialize() == APR_SUCCESS else {
print("Can't initialize apr_pool")
exit(1)
}
var pool: OpaquePointer? = nil
guard apr_pool_create_unmanaged_ex(&pool, nil, nil) == APR_SUCCESS else {
apr_pool_terminate()
print("Can't create unmanaged pool")
exit(1)
}
// Create big tree in first pool
let treePtr = CreateTree(maxDepth+1, pool!)
let tree = UnsafeMutablePointer<Node>(treePtr)
// Swift binary-trees program should use ARC
print("stretch tree of depth \(maxDepth+1)\t check: \(tree[0].check())")
// Release big tree
apr_pool_clear(pool!);
// Create long living tree
let longLivingTreePtr = CreateTree(maxDepth, pool!)
// Allocate trees of increasing depth up to maxDepth depth
let depths = (maxDepth-minDepth)/2+1
var results = [String](repeating: "", count: depths)
let rQueue = DispatchQueue(label: "Result", attributes: [])
let queue = DispatchQueue(label: "Worker", attributes: .concurrent)
DispatchQueue.concurrentPerform(iterations: depths) {
idx in
// Create depth pool
var depthPool: OpaquePointer? = nil
guard apr_pool_create_unmanaged_ex(&depthPool, nil, nil) == APR_SUCCESS else {
apr_pool_terminate()
print("Can't create unmanaged depth pool")
exit(1)
}
let currentDepth = minDepth + idx * 2
let iterations = 1 << (maxDepth - currentDepth + minDepth)
var totalCheckSum = 0
for _ in 1...iterations {
let tree1Ptr = CreateTree(currentDepth, depthPool!)
let tree1 = UnsafeMutablePointer<Node>(tree1Ptr)
totalCheckSum += tree1[0].check()
apr_pool_clear(depthPool!);
}
// Release depth pool
apr_pool_destroy(depthPool!)
// Store result string
rQueue.async {
results[idx] = "\(iterations)\t trees of depth \(currentDepth)\t check: \(totalCheckSum)"
}
}
// Print output in correnct order
rQueue.sync {
for result in results {
print(result)
}
}
let longLivingTree = UnsafeMutablePointer<Node>(longLivingTreePtr)
print("long lived tree of depth \(maxDepth)\t check: \(longLivingTree[0].check())")
// Release long living tree
apr_pool_destroy(pool!);
apr_pool_terminate()
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
Swift version 5.1.3 (swift-5.1.3-RELEASE)
Target: x86_64-unknown-linux-gnu
Tue, 05 May 2020 19:29:33 GMT
MAKE:
/opt/src/swift-5.1.3-RELEASE-ubuntu18.04/usr/bin/swiftc binarytrees.swift-9.swift -Ounchecked -target-cpu core2 -o binarytrees.swift-9.swift_run
<unknown>:0: warning: argument unused during compilation: '-mcpu=core2'
binarytrees.swift-9.swift:12:8: error: no such module 'apr'
import apr
^
make: [/home/dunham/8000-benchmarksgame/nanobench/makefiles/u64q.programs.Makefile:412: binarytrees.swift-9.swift_run] Error 1 (ignored)
8.13s to complete and log all make actions
COMMAND LINE:
./binarytrees.swift-9.swift_run 7
MAKE ERROR