gpt4 book ai didi

swift - str = str + "abc"比 str = "abc"+ str 慢?

转载 作者:搜寻专家 更新时间:2023-10-31 22:20:29 29 4
gpt4 key购买 nike

你信吗?我有一个这样的循环(请原谅任何错误,我不得不大量编辑大量信息和变量名称,相信我它有效)。

...旧示例已删除,请参见下面的代码...

如果我将那些中间的 str = "Blah\(odat.count)"+ str 类型行更改为 str = str + "Blah\(odat.count)" UI 停止了,我得到了色轮。 NSTextField 确实到达了第一个 self.display.string... 但随后卡住了。

我是一个多线程新手,所以请随时纠正我的方法。希望我想要的很清楚。

我不得不承认工作版本也有点卡顿,但从未真正卡住。典型值为 n = 70,var3 = 7。

编辑:

这是一个完整的示例。只需链接 TextView 、进度条和按钮。尝试在主要功能之间切换。

//
// Controllers.swift
//
//

import Cocoa

class MainController: NSObject {

@IBOutlet var display: NSTextView!
@IBOutlet weak var prog: NSProgressIndicator!

@IBAction func go1(sender: AnyObject) {
theRoutine(70)
}

@IBAction func go2(sender: AnyObject) {
theRoutine(50)
}

class SomeClass {
var x: Int
var y: Int
var p: Double

init?(size: Int, pro: Double) {
x = size
y = size
p = pro
}
}

func theRoutine(n: Int) {
prog.hidden = false
prog.doubleValue = 0
prog.maxValue = 7 * 40
let priority = DISPATCH_QUEUE_PRIORITY_HIGH
dispatch_async(dispatch_get_global_queue(priority, 0)) {
self.theFunc(n, var1: 0.06, var2: 0.06, var3: 7)
self.theFunc(n, var1: 0.1*log(Double(n))/Double(n), var2: 0.3*log(Double(n))/Double(n), var3: 7)
dispatch_async(dispatch_get_main_queue()) {
self.prog.hidden = true
self.appOut("done!")
}
}
}

//This doesn't
// func theFunc(n: Int, var1: Double, var2: Double, var3: Int) {
// var m: AnEnum
// var gra: SomeClass
// var p = var1
// for _ in 0...(var3 - 1) {
// var str = "blah \(p)\n"
// for _ in 1...20 {
// gra = SomeClass(size: n, pro: p)!
// m = self.doSomething(gra)
// switch m {
// case .First(let dat):
// str = str + "Blah:\n\(self.arrayF(dat, transform: {"blah\($0)blah\($1)=blah"}))" + "\n\n" + str
// case .Second(let odat):
// str = str + "Blah\(odat.count) blah\(self.arrayF(odat, transform: {"bl\($1)"}))" + "\n\n" + str
// }
// dispatch_async(dispatch_get_main_queue()) {
// self.prog.incrementBy(1)
// }
// }
// dispatch_async(dispatch_get_main_queue()) {
// // update some UI
// self.display.string = str + "\n" + (self.display.string ?? "")
// }
// p += var2
// }
// }

//This works
func theFunc(n: Int, var1: Double, var2: Double, var3: Int) {
var m: AnEnum
var gra: SomeClass
var p = var1
for _ in 0...(var3 - 1) {
var str = "blah \(p)\n"
for _ in 1...20 {
gra = SomeClass(size: n, pro: p)!
m = self.doSomething(gra)
switch m {
case .First(let dat):
str = "Blah:\n\(self.arrayF(dat, transform: {"blah\($0)blah\($1)=blah"}))" + "\n\n" + str
case .Second(let odat):
str = "Blah\(odat.count) blah\(self.arrayF(odat, transform: {"bl\($1)"}))" + "\n\n" + str
}
dispatch_async(dispatch_get_main_queue()) {
self.prog.incrementBy(1)
}
}
dispatch_async(dispatch_get_main_queue()) {
// update some UI
self.display.string = str + "\n" + (self.display.string ?? "")
}
p += var2
}
}

func doSomething(G: SomeClass) -> AnEnum {
usleep(30000)
if drand48() <= G.p {
return AnEnum.First([0, 0])
} else {
return AnEnum.Second([1, 1, 1])
}
}

enum AnEnum {
case First([Int])
case Second([Int])
}

func appOut(out: String?) {
if out != nil {
display.string = out! + "\n\n" + (display.string ?? "")
}
}

func arrayF(array: [Int], transform: (index: Int, value: Int) -> String) -> String {
let arr = Array(0...(array.count - 1))
return "[\(arr.map{transform(index: $0, value: array[$0])}.joinWithSeparator(", "))]"
}
}

最佳答案

因为除了

之外,你并没有真正问其他问题

Can you believe it?

我会告诉你我当然可以,但说真的,在很多情况下,前置某些东西可能比追加慢/快。以链表为例。如果您没有持有对列表最后一个元素的引用,则 Prepend 是 O(1) 并且 Append 是 O(N)。

我将要点放在一起,只是对那个特定问题进行计时,并且在 5-6 次运行中它似乎没有显着差异,但是在我的机器上 prepend 仍然慢 10%。

有趣的是,对于您的情况,您基本上有 4 种在 Swift 中连接字符串的方法:

  • 添加到累加器 str = newstr + str
  • 追加到累加器 str = str + newstr
  • 追加变异str.append(newstr)
  • 使用好旧的数组作为字符串缓冲区并一次加入所有内容 a = []; a.追加(x); str = a.joined(分隔符: "")

在我的机器上,它们似乎几乎同时偏离,典型的时间如下:

prepend
real 0m0.082s
user 0m0.060s
sys 0m0.018s

append
real 0m0.070s
user 0m0.049s
sys 0m0.018s

append mutate
real 0m0.075s
user 0m0.054s
sys 0m0.019s

join
real 0m0.086s
user 0m0.064s
sys 0m0.020s

追加最快。

您可以在我的要点中看到所有四种情况的代码 https://gist.github.com/ojosdegris/df72a94327d12a67fe65e5989f9dcc53

如果您查看 Github 上的 Swift 源代码,您会看到:

@effects(readonly)
@_semantics("string.concat")
public static func + (lhs: String, rhs: String) -> String {
if lhs.isEmpty {
return rhs
}
var lhs = lhs
lhs._core.append(rhs._core)
return lhs
}

所以当累加器字符串增长时可能发生的事情是复制它的成本更高。

关于swift - str = str + "abc"比 str = "abc"+ str 慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39376005/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com