You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In programs using CoW data structures, the _modify accessor can be the difference between a program that performs fantastically well and one that performs very poorly. Unfortunately, getting Swift to actually use the _modify accessor is deeply non-obvious: in practice, _modify will only be used when the load/store operation is expressible in one line. The actual logic may be arbitrarily complex (for example, calling a very complex mutating function, i.e. array[index].myVeryComplexMutatingFunction(), but the point of invocation of that operation must be expressed in one line.
I suspect substantial performance wins would be available in naive programs if the optimiser could observe that the _modify accessor could have been used. For example, consider the following program:
structTest {
privatevarbacking: Int = 0vartest: Int {
get {
print("\tget")
returnself.backing
}
set {
print("\tset")
self.backing = newValue
}
_modify {
print("\tget modify")
yield &self.backingprint("\tset modify")
}
}
}
@discardableResultfunceasy() -> Int {
print("easy")
vart = Test()
t.test += 5returnt.test
}
@discardableResultfunchard() -> Int {
print("hard")
vart = Test()
vartemp = t.testtemp += 5t.test = tempreturnt.test
}
@discardableResultfuncsetOnly() -> Int {
print("setOnly")
vart = Test()
t.test = 5returnt.test
}
easy()
hard()
setOnly()
which indicates that only the direct mutation actually uses the _modify accessor.
That's very disappointing! Some analysis of the ownership of t in the hard case should observe that no operation between the load and the store either modifies or copies t. As a result, we can behave as if t were exclusively owned during the entire intervening period, and replace the get/set with a _modify.
I don't know how hard this work would be, but it has the potential to make a bunch of programs substantially faster, as well as to remove a "one weird trick to make your programs fast" wart that Swift currently has.
The text was updated successfully, but these errors were encountered:
Additional Detail from JIRA
md5: 79e96d8a1b91323cc0428090f3176d7a
Issue Description:
In programs using CoW data structures, the
_modify
accessor can be the difference between a program that performs fantastically well and one that performs very poorly. Unfortunately, getting Swift to actually use the_modify
accessor is deeply non-obvious: in practice,_modify
will only be used when the load/store operation is expressible in one line. The actual logic may be arbitrarily complex (for example, calling a very complex mutating function, i.e.array[index].myVeryComplexMutatingFunction()
, but the point of invocation of that operation must be expressed in one line.I suspect substantial performance wins would be available in naive programs if the optimiser could observe that the
_modify
accessor could have been used. For example, consider the following program:When executed with
-O
, this program will print:which indicates that only the direct mutation actually uses the
_modify
accessor.That's very disappointing! Some analysis of the ownership of
t
in thehard
case should observe that no operation between the load and the store either modifies or copiest
. As a result, we can behave as ift
were exclusively owned during the entire intervening period, and replace theget
/set
with a_modify
.I don't know how hard this work would be, but it has the potential to make a bunch of programs substantially faster, as well as to remove a "one weird trick to make your programs fast" wart that Swift currently has.
The text was updated successfully, but these errors were encountered: