- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在使用 Swift 开发一款游戏,我有一个静态位置数据数组,用于在游戏循环中进行处理。我最初是使用一个结构数组来保存这些数据,但我决定切换到类,这样我就可以使用引用了。然而,在进行更改和分析之后,我注意到 CPU 在处理这些数据的方法上花费的时间比我在使用 Structs 时花费的时间多得多。
所以我决定创建一个简单的测试来查看发生了什么。
final class SomeClass {}
struct SomeStruct {}
let classes = [
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
]
let structs = [
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
]
func test1() {
for i in 0...10000000 {
for s in classes {}
}
}
func test2() {
for i in 0...10000000 {
for s in structs {}
}
}
Test1 耗时 15.4722579717636 秒,而 Test2 仅耗时 0.276068031787872 秒。连续迭代结构数组的速度提高了 56 倍。 所以我的问题是,这是为什么?我正在寻找详细的答案。如果我不得不猜测,我会说结构本身按顺序存储在内存中,而类仅存储为地址。所以他们每次都需要取消引用。不过话又说回来,难道每次都需要复制结构体吗?
旁注:这两个数组都很小,但我正在连续迭代它们。如果我将代码更改为迭代 一次 但使数组非常大,如下所示:
for i in 0...10000000 {
structs.append(SomeStruct())
classes.append(SomeClass())
}
func test1() {
for s in classes {}
}
func test2() {
for s in structs {}
}
然后我得到以下结果:Test1 需要 0.841085016727448 秒,而 Test2 需要 0.00960797071456909 秒。这些结构的速度提高了 88 倍。
我使用的是 OS X 发布版本,优化级别设置为 Fastest,Smallest [-Os]
根据要求,我编辑了这个问题以包含结构和类不再为空的测试。他们使用我在游戏中使用的相同属性。仍然没有改变。结构仍然快得多,我不知道为什么。希望有人能提供答案。
import Foundation
final class StructTest {
let surfaceFrames = [
SurfaceFrame(a: SurfacePoint(x: 0, y: 410), b: SurfacePoint(x: 0, y: 400), c: SurfacePoint(x: 875, y: 410), surfaceID: 0, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 880, y: 304), b: SurfacePoint(x: 880, y: 294), c: SurfacePoint(x: 962, y: 304), surfaceID: 1, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 787, y: 138), b: SurfacePoint(x: 791, y: 129), c: SurfacePoint(x: 1031, y: 248), surfaceID: 2, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 523, y: 138), b: SurfacePoint(x: 523, y: 128), c: SurfacePoint(x: 806, y: 144), surfaceID: 3, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1020, y: 243), b: SurfacePoint(x: 1020, y: 233), c: SurfacePoint(x: 1607, y: 241), surfaceID: 4, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1649, y: 304), b: SurfacePoint(x: 1649, y: 294), c: SurfacePoint(x: 1731, y: 305), surfaceID: 5, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1599, y: 240), b: SurfacePoint(x: 1595, y: 231), c: SurfacePoint(x: 1852, y: 128), surfaceID: 6, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1807, y: 141), b: SurfacePoint(x: 1807, y: 131), c: SurfacePoint(x: 2082, y: 138), surfaceID: 7, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 976, y: 413), b: SurfacePoint(x: 976, y: 403), c: SurfacePoint(x: 1643, y: 411), surfaceID: 8, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1732, y: 410), b: SurfacePoint(x: 1732, y: 400), c: SurfacePoint(x: 2557, y: 410), surfaceID: 9, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 2130, y: 490), b: SurfacePoint(x: 2138, y: 498), c: SurfacePoint(x: 2109, y: 512), surfaceID: 10, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1598, y: 828), b: SurfacePoint(x: 1597, y: 818), c: SurfacePoint(x: 1826, y: 823), surfaceID: 11, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 715, y: 826), b: SurfacePoint(x: 715, y: 816), c: SurfacePoint(x: 953, y: 826), surfaceID: 12, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 840, y: 943), b: SurfacePoint(x: 840, y: 933), c: SurfacePoint(x: 920, y: 943), surfaceID: 13, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1005, y: 1011), b: SurfacePoint(x: 1005, y: 1001), c: SurfacePoint(x: 1558, y: 1011), surfaceID: 14, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1639, y: 943), b: SurfacePoint(x: 1639, y: 933), c: SurfacePoint(x: 1722, y: 942), surfaceID: 15, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1589, y: 825), b: SurfacePoint(x: 1589, y: 815), c: SurfacePoint(x: 1829, y: 825), surfaceID: 16, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 0, y: 0), b: SurfacePoint(x: 1, y: 1), c: SurfacePoint(x: 2, y: 2), surfaceID: 17, dynamic:true)
]
func run() {
let startTime = CFAbsoluteTimeGetCurrent()
for i in 0 ... 10000000 {
for s in surfaceFrames {
}
}
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
println("Time elapsed \(timeElapsed) s")
}
}
struct SurfacePoint {
var x,y: Int
}
struct SurfaceFrame {
let a,b,c :SurfacePoint
let surfaceID: Int
let dynamic: Bool
}
import Foundation
final class ClassTest {
let surfaceFrames = [
SurfaceFrame(a: SurfacePoint(x: 0, y: 410), b: SurfacePoint(x: 0, y: 400), c: SurfacePoint(x: 875, y: 410), surfaceID: 0, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 880, y: 304), b: SurfacePoint(x: 880, y: 294), c: SurfacePoint(x: 962, y: 304), surfaceID: 1, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 787, y: 138), b: SurfacePoint(x: 791, y: 129), c: SurfacePoint(x: 1031, y: 248), surfaceID: 2, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 523, y: 138), b: SurfacePoint(x: 523, y: 128), c: SurfacePoint(x: 806, y: 144), surfaceID: 3, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1020, y: 243), b: SurfacePoint(x: 1020, y: 233), c: SurfacePoint(x: 1607, y: 241), surfaceID: 4, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1649, y: 304), b: SurfacePoint(x: 1649, y: 294), c: SurfacePoint(x: 1731, y: 305), surfaceID: 5, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1599, y: 240), b: SurfacePoint(x: 1595, y: 231), c: SurfacePoint(x: 1852, y: 128), surfaceID: 6, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1807, y: 141), b: SurfacePoint(x: 1807, y: 131), c: SurfacePoint(x: 2082, y: 138), surfaceID: 7, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 976, y: 413), b: SurfacePoint(x: 976, y: 403), c: SurfacePoint(x: 1643, y: 411), surfaceID: 8, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1732, y: 410), b: SurfacePoint(x: 1732, y: 400), c: SurfacePoint(x: 2557, y: 410), surfaceID: 9, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 2130, y: 490), b: SurfacePoint(x: 2138, y: 498), c: SurfacePoint(x: 2109, y: 512), surfaceID: 10, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1598, y: 828), b: SurfacePoint(x: 1597, y: 818), c: SurfacePoint(x: 1826, y: 823), surfaceID: 11, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 715, y: 826), b: SurfacePoint(x: 715, y: 816), c: SurfacePoint(x: 953, y: 826), surfaceID: 12, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 840, y: 943), b: SurfacePoint(x: 840, y: 933), c: SurfacePoint(x: 920, y: 943), surfaceID: 13, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1005, y: 1011), b: SurfacePoint(x: 1005, y: 1001), c: SurfacePoint(x: 1558, y: 1011), surfaceID: 14, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1639, y: 943), b: SurfacePoint(x: 1639, y: 933), c: SurfacePoint(x: 1722, y: 942), surfaceID: 15, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 1589, y: 825), b: SurfacePoint(x: 1589, y: 815), c: SurfacePoint(x: 1829, y: 825), surfaceID: 16, dynamic:false),
SurfaceFrame(a: SurfacePoint(x: 0, y: 0), b: SurfacePoint(x: 1, y: 1), c: SurfacePoint(x: 2, y: 2), surfaceID: 17, dynamic:true)
]
func run() {
let startTime = CFAbsoluteTimeGetCurrent()
for i in 0 ... 10000000 {
for s in surfaceFrames {
}
}
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
println("Time elapsed \(timeElapsed) s")
}
}
struct SurfacePoint {
var x,y: Int
}
final class SurfaceFrame {
let a,b,c :SurfacePoint
let surfaceID: Int
let dynamic: Bool
init(a: SurfacePoint, b: SurfacePoint, c: SurfacePoint, surfaceID: Int, dynamic: Bool) {
self.a = a
self.b = b
self.c = c
self.surfaceID = surfaceID
self.dynamic = dynamic
}
}
在这个测试中,类用了 14.5261079668999 秒,而结构测试只用了 0.310304999351501 秒。结构速度提高了 47 倍。
最佳答案
正如 Martin R 所建议的,我对这两个测试进行了概要分析,实际上,保留/释放调用使得类数组的迭代比结构数组的迭代慢得多。需要说明的是,这是我运行的测试。
import Foundation
final class SomeClass {}
struct SomeStruct {}
var classes = [
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
SomeClass(),
]
var structs = [
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
SomeStruct(),
]
let startTime = CFAbsoluteTimeGetCurrent()
/*
structTest()
classTest()
*/
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
println("Time elapsed \(timeElapsed) s")
func structTest() {
for i in 0 ... 1000000 {
for e in structs {}
}
}
func classTest() {
for i in 0 ... 1000000 {
for e in classes {}
}
}
以下是使用仪器对这两个测试进行分析的图片。只需将运行时间相加,您就可以看到类测试在每次迭代期间几乎将所有时间都花在了保留/释放上。我很想知道 Swift 2.0 如何处理这个问题。
结构
类
所以出于好奇,我想如果我可以通过直接在数组上进行指针运算来绕过保留/释放调用会发生什么(旁注:我建议你永远不要这样做在真实的应用程序中)。所以我创建了最后一个测试。但是在这个测试中,我不会多次迭代数组,而是创建一个大数组并迭代一次,因为无论如何这是大部分开销发生的地方。我还决定在此测试中访问属性以减少优化中的歧义。
下面是最终测试的结果:
下面是测试代码。
final class SomeClass {
var a: Int
init(a: Int) {
self.a = a
}
}
struct SomeStruct {
var a: Int
init(a: Int) {
self.a = a
}
}
var classes: [SomeClass] = []
var structs: [SomeStruct] = []
var total: Int = 0
for i in 0 ... 100000000 {
classes.append(SomeClass(a:i))
structs.append(SomeStruct(a:i))
}
let startTime = CFAbsoluteTimeGetCurrent()
/*structTest()
classTest()
structTestPointer()
classTestPointer()*/
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
println("Time elapsed \(timeElapsed) s")
func structTest() {
for someStruct in structs {
let a = someStruct.a
total = total &+ a
}
}
func structTestPointer() {
var pointer = UnsafePointer<SomeStruct>(structs)
for j in 0 ..< structs.count {
let someStruct = pointer.memory
let a = someStruct.a
total = total &+ a
pointer++
}
}
func classTest() {
for someClass in classes {
let a = someClass.a
total = total &+ a
}
}
func classTestPointer() {
var pointer = UnsafePointer<SomeClass>(classes)
for j in 0 ..< classes.count {
let someClass = pointer.memory
let a = someClass.a
total = total &+ a
pointer++
}
}
关于arrays - 为什么连续迭代结构数组比类数组快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31032772/
如果您有超过 1 个具有相同类名的(动态)文本框,并使用 jquery 循环遍历每个所述文本框,您是否可以假设每次选择文本框的顺序都是相同的? 示例: 文本框 1 值 = 1文本框 2 值 = 2文本
有人知道为什么这段代码无法顺利运行吗?它似乎不喜欢使用yield关键字进行迭代:我正在尝试从任何级别的列表或字典中挖掘所有数字(对列表特别感兴趣)。在第二次迭代中,它找到 [2,3] 但无法依次打印
我关于从 mysql 数据库导出数据并将其保存到 Excel 文件(多表)的创建脚本。我需要让细胞动态基因化。该脚本正确地显示了标题,但数据集为空。当我“回显”$value 变量时,我检查了数据是否存
我正在尝试在 Python 中运行模拟,由此我绘制了一个数组的随机游走图,给定了两个变量参数的设定水平。 但是,我遇到了一个问题,我不确定如何迭代以便生成 250 个不同的随机数以插入公式。例如我已经
我是学习 jquery 的新手,所以如果这是一个相对简单的问题,我深表歉意。我有一个 ID 为 ChartstoDisplay 的 asp.net 复选框列表。我正在尝试创建 jquery 来根据是否
我正在尝试根据在任意数量的部分中所做的选择找出生成有效案例列表的最佳方法。也许它不是真正的算法,而只是关于如何有效迭代的建议,但对我来说这似乎是一个算法问题。如果我错了,请纠正我。实现实际上是在 Ja
如果我使用 sr1 为 www.google.com 发送 DNSQR,我会收到几个 DNSRR(s) 作为回复,例如(使用 ans[DNSRR].show() 完成): ###[ DNS Resou
假设有这样一个实体类 @Entity public class User { ... public Collection followers; ... } 假设用户有成千上万的用户关注者。我想分页..
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: Nested jQuery.each() - continue/break 这是我的代码: var steps =
我刚从 F# 开始,我想遍历字典,获取键和值。 所以在 C# 中,我会说: IDictionary resultSet = test.GetResults; foreach (DictionaryEn
我知道已经有很多关于如何迭代 ifstream 的答案,但没有一个真正帮助我找到解决方案。 我的问题是:我有一个包含多行数据的txt文件。 txt 文件的第一行告诉我其余数据是如何组成的。例如这是我的
我有 12 个情态动词。我想将每个模态的 .modal__content 高度与 viewport 高度 进行比较,并且如果特定模态 .modal__content 高度 vh addClass("c
在此JSFiddle (问题代码被注释掉)第一次单击空单元格会在隐藏输入中设置一个值,并将单元格的背景颜色设置为绿色。单击第二个空表格单元格会设置另一个隐藏输入的值,并将第二个单元格的背景颜色更改为红
这是一个非常具体的问题,我似乎找不到任何特别有帮助的内容。我有一个单链表(不是一个实现的链表,这是我能找到的全部),其中节点存储一个 Student 对象。每个 Student 对象都有变量,尽管我在
有没有办法迭代 IHTMLElementCollection? 比如 var e : IHTMLLinkElement; elementCollection:IHTMLElementCollect
我正在尝试用 Java 取得高分。基本上我想要一个 HashMap 来保存 double 值(因此索引从最高的 double 值开始,这样我更容易对高分进行排序),然后第二个值将是客户端对象,如下所示
我想在宏函数中运行 while/until 循环,并限制其最大迭代次数。我找到了如何在“通常”sas 中执行此操作: data dataset; do i=1 to 10 until(con
Iterator iterator = plugin.inreview.keySet().iterator(); while (iterator.hasNext()) { Player key
晚上好我有一个简单的问题,我警告你我是序言的新手。假设有三个相同大小的列表,每个列表仅包含 1、0 或 -1。我想验证对于所有 i,在三个列表的第 i 个元素中,只有一个非零。 此代码针对固定的 i
我在 scheme 中构建了一个递归函数,它将在某些输入上重复给定函数 f, n 次。 (define (recursive-repeated f n) (cond ((zero? n) iden
我是一名优秀的程序员,十分优秀!