title: Swift performance: getting rid of ContiguousArrayStorage deinit
body: <p>I'm trying to optimize some loop in Swift.</p>
  
  <p>I have this class,</p>
  
  <pre><code>class SphericalHarmonics {
      /** SphericalHarmonics Samples */
      struct SHSample {
          var sph:    Spherical
          var vec:    Vector3
          var coeff:  [Double]
      }
  
      let numBands    : UInt
      let numCoeffs   : UInt
      let numSamples  : UInt
      var samples     : [SHSample]
      var coeffs      : [Vector3]
  </code></pre>
  
  <p>and in init I initialize all the matrices and then loop over 10000 samples accessing those matrices again.</p>
  
  <pre><code>    let coefficients = [Double](count: Int(numCoeffs), repeatedValue: 0)
      let emptySample = SHSample(sph: Spherical(), vec: Vector3(), coeff: coefficients)
      samples = [SHSample](count: Int(self.numSamples), repeatedValue: emptySample)
      coeffs = [Vector3](count: Int(numCoeffs), repeatedValue: Vector3())
      // ...
      var i = 0 // array index
      for a in 0..&lt;numSamplesSqrt {
          for b in 0..&lt;numSamplesSqrt {
              // ...
              samples[i].sph = Spherical(r: 1.0, θ: Float(θ), φ: Float(φ))
              // convert spherical coords to unit vector
              samples[i].vec = samples[i].sph.ToVector3()
              // precompute all SH coefficients for this sample
              for l in 0..&lt;Int(numBands) {
                  for m in -l...l {
                      let ci = l * (l+1) + m // coefficient index
                      samples[i].coeff[ci] = SH(l: l,m: m,θ: θ,φ: φ)
                  }
              }
              ++i
  </code></pre>
  
  <p>The first mistake here was reading from samples[i]. A profiling session revealed that Swift.Array._copyBuffer of SHSample was taking 2.2 sec, and ContiguousArrayStorage._deallocating_deinit was taking 2 sec. I did this simple change and saved 4 seconds :)</p>
  
  <pre><code>            let sph = Spherical(r: 1.0, θ: Float(θ), φ: Float(φ))
              samples[i].sph = sph
              // convert spherical coords to unit vector
              samples[i].vec = sph.ToVector3()
  </code></pre>
  
  <p>However, there are still 200ms of ContiguousArrayStorage._deallocating_deinit that come from the last inner loop where I'm accessing samples[i].coeff[ci]. I don't really understand why deinit needs to be called, since the arrays are already created and I'm just modifying their data.</p>
  
  <p>Any idea why?</p>
  
  <p>(If you want to see the full code, it's here: <a href="https://github.com/endavid/Harmonikr/blob/master/Harmonikr/math/SphericalHarmonics.swift" rel="nofollow">https://github.com/endavid/Harmonikr/blob/master/Harmonikr/math/SphericalHarmonics.swift</a> )</p>