通用序列和生成器的极端性能问题

dre*_*wag 5 generics performance swift

我正在尝试创建自己的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
Run Code Online (Sandbox Code Playgroud)

注意:显然这是一个无用的类型,因为它只生成与生成类型相同的东西,但我的实际类型稍微复杂和有用.

正如您在我的代码注释中所看到的,构造函数的最后一个版本存在极端的性能问题.它花费了大约18秒钟,而不是花费十分之一秒.

我甚至没有做任何实际的一代.我想它与确定类型有关,因为如果数组都是文字并且提供了测试方法,那只是一个问题.如果我将测试属性声明更改为硬编码为Int,也没有性能问题:

let test: ((element: Int) -> Bool)?
Run Code Online (Sandbox Code Playgroud)

任何人都可以了解可能导致此性能问题的原因以及我如何解决这个问题?

jtb*_*des 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]
                          ...
Run Code Online (Sandbox Code Playgroud)

提交错误!