Data -> NSData causes huge slowdown in NEPacketTunnelProvider

Not sure if this is a feature or a bug, but thought I would bring it up. I was experiencing very slow speeds in my NEPacketTunnelProvider subclass. I finally found the issue. It seems like a bug, but maybe it is supposed to work this way.

This function, called for each packet up/down, needs a [UInt8] array from a Data object. This is what works as expected, I get close to my expected speed test of 28Mpbs:

public mutating func parseL4Proto(packet: Data, l4HeaderOffset: Int) {
    let byteArray = [UInt8](packet)
        .
        .
        .

If I do this instead, it compiles and runs, but my speed test now returns around 7Mbps.

public mutating func parseL4Proto(packet: Data, l4HeaderOffset: Int) {
    let data = (packet as NSData)
    let byteArray = [UInt8](data)
        .
        .
        .

Very repeatable. Change those lines and the speed test results are way off.

Everything is working now, but I am posting this for others who may encounter it. Bug? Feature?

There are a lot of spinning plates here — including dispatch_data_t, NSData, Data, and [UInt8] — so it’s hard to say exactly what’s going on. Having said that, it’s not a huge surprise that bouncing through an Objective-C type slows thing down because the flexibility of the Objective-C runtime puts strict limits on how much the compiler can optimise.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Data -> NSData causes huge slowdown in NEPacketTunnelProvider
 
 
Q