我正在尝试创建自己的Generic序列类型。我可以创建的最简单的示例显示性能问题:
// Warning, this code will cause Xcode to hang if you run this in a playground
// Instead I recommend running it in the REPL or running it with the command
// line tool
struct TakeGenerator<T: GeneratorType>: GeneratorType {
typealias Element = T.Element
var generator: T
mutating func next() -> Element? {
return self.generator.next()
}
}
struct Take<T: SequenceType>: SequenceType {
typealias Generator = TakeGenerator<T.Generator>
let seq: T
let test: ((element: T.Generator.Element) -> Bool)?
func generate() -> Generator {
return Generator(generator: seq.generate())
}
}
// NOTE: The times below reflect how long it takes to run this code from
// the command line with only that line uncommented (other than the type
// declarations)
//
// The command I use is: `time xcrun swift <filename>`
var array = [1,2,3,4]
Take(seq: array, test: {$0 < 3}) // 0.104 seconds to execute
Take(seq: [1,2,3,4], test: nil) // 0.100 seconds to execute
Take(seq: ([1,2,3,4] as [Int]), test: {$0 < 3}) // 0.140 seconds to execute
Take(seq: [1,2,3,4], test: {$0 < 3}) // 17.939 seconds to execute
注意:显然这是一种无用的类型,因为它只生成与生成的类型相同的东西,但我的实际类型稍微复杂一些。
正如您在我的代码注释中所看到的,构造函数的最后一个版本存在极端的性能问题。它不需要花费十分之一秒,而是花费将近18秒。
我甚至没有做任何实际的一代。我想它与确定类型有关,因为如果数组都是文字并且提供了测试方法,那只是一个问题。如果我将测试属性声明更改为硬编码为Int:
,也没有性能问题let test: ((element: Int) -> Bool)?
任何人都可以了解可能导致此性能问题的原因以及我如何解决这个问题?
答案 0 :(得分:2)
这绝对是一个类型推断问题。使用swiftc test.swift
进行编译会占用大部分时间;正在运行./test
。此外,sample
显示大部分时间花在
Call graph:
2677 Thread_113719 DispatchQueue_1: com.apple.main-thread (serial)
2677 start (in libdyld.dylib) + 1 [0x7fff946715c9]
2677 main (in swift) + 1725 [0x105919a2d]
2677 frontend_main(llvm::ArrayRef<char const*>, char const*, void*) (in swift) + 1960 [0x10591b908]
2677 swift::CompilerInstance::performSema() (in swift) + 2064 [0x105b7de80]
2677 swift::performTypeChecking(swift::SourceFile&, swift::TopLevelContext&, unsigned int) (in swift) + 1464 [0x106830d08]
2677 swift::TypeChecker::typeCheckTopLevelCodeDecl(swift::TopLevelCodeDecl*) (in swift) + 136 [0x10687d518]
2677 swift::ASTVisitor<(anonymous namespace)::StmtChecker, void, swift::Stmt*, void, void, void, void>::visit(swift::Stmt*) (in swift) + 291 [0x10687d683]
2677 swift::TypeChecker::typeCheckExpression(swift::Expr*&, swift::DeclContext*, swift::Type, swift::Type, bool, swift::FreeTypeVariableBinding, swift::ExprTypeCheckListener*) (in swift) + 971 [0x10683a2ab]
2677 swift::constraints::ConstraintSystem::solve(llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::FreeTypeVariableBinding) (in swift) + 363 [0x10681e8fb]
2677 swift::constraints::ConstraintSystem::solve(llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::FreeTypeVariableBinding) (in swift) + 945 [0x10681eb41]
...