繁体   English   中英

我如何发送(和接收)从Swift到Objective c ++到c ++的超大型浮动数组,然后再备份到Swift?

[英]How can I send (and receive) extremely large floating arrays from Swift to Objective c++ to c++, and then back up to Swift?

我是一名Swift程序员,我的Objective-c ++和c ++经验与我的Swift经验绝不相称。 我已经成功地从Swift-> Objc ++-> c ++(在其中进行处理)发送和接收浮点数的小数组,然后备份到Objc ++和Swift。 我们正在C ++中进行大量工作,由于以下几个原因,我们暂时无法迁移到Swift(其中一个原因是c ++比Swift更有效)。

C ++程序完成的工作是在非常大的浮点数组上。 目前,这些浮点数组由c ++程序通过CSV文件发送和使用。 我们希望删除这些CSV文件,以便消除在磁盘上读写的需要。 我们想直接处理浮点数数组。

以下代码适用于小型数组。 但是,如果有300,000+的大型数组,则该程序仅会由于内存问题而在iOS设备上崩溃,然后在模拟器上,下面的Objective-c ++代码占用高达59 GB的内存!

有人可以解释一下,并告诉我一种更好的方法来发送和接收从Swift到Objc ++到C ++的大型浮动数组,然后再备份到Swift吗?

目前,我将保留.h和.hpp代码,仅显示Swift,.mm和.cpp代码。

SWIFT CODE:
let objcCppWrapper = ObjcCppWrapper()
        let pointer: UnsafeMutablePointer<Float> = UnsafeMutablePointer(mutating: floatArray)
        if let cppArraySameSize = objcCppWrapper.cppProcessSwiftArray(pointer, number_elements: Int32(floatArray.count)) {
            let newArraySameSizePointer: UnsafeMutablePointer<Any> = UnsafeMutablePointer(mutating: cppArraySameSize)
            let size = Int32(floatArray.count)
            let floatsSameSizeAny : [Any] = Array(UnsafeBufferPointer(start: newArraySameSizePointer, count: Int(size)))
            print("Swift: 'floatsSameSizeAny' size is \(floatsSameSizeAny.count)")
        }
OBJECTIVE-C++ CODE:
-(NSArray *) cppProcessSwiftArray:(float [])array number_elements:(int )number_elements{

    //Transform the float array into a vector array
    std::vector<float> arrayVector(number_elements);

    for(int j=0; j < number_elements; j++){
        arrayVector[j] = array[j];
    }

    CppProcess cppProcess;
    std::vector<float>  cppArray = cppProcess.cppProcessSwiftArray(arrayVector);

    //USES WAYYYYYY TOO MUCH MEMORY! UP TO 59 GB ON SIMULATOR, CRASHES TERMINATES IN IOS DEVICE DU TO MEMORY ISSUE.
    NSArray *returnNsArray = [NSArray array];
    for(int j=0; j < cppArray.size(); j++){
        returnNsArray = [returnNsArray arrayByAddingObject:[NSNumber numberWithFloat:cppArray[j]]];
    }

    return returnNsArray;
}
C++ CODE:
vector<float> CppProcess::cppProcessSwiftArray(vector<float> arrayOfFloats) {

    cout << "CPP: Received an array is of size " << arrayOfFloats.size() << '\n';

    std::vector<float> returnedSameSizeArray(arrayOfFloats.size());

    //For the moment, only create an arbitrary array of same size and return it...
    for(int j=0; j < arrayOfFloats.size(); j++){
        returnedSameSizeArray[j] = j ;
    }

    return returnedSameSizeArray;
}

您的Swift代码展示了Swift指针和数组的错误用法。 您使用UnsafeMutablePointer.init(mutating:)可能会导致灾难性的结果,包括崩溃或变量意外更改。

同样在C ++代码中,为什么vector值传递vector 您最好使用引用以避免复制。

无论如何,如果您确实在意内存效率,那么最好注意两件事:

  • 切勿使用NSArray表示基本类型的数组

    NSNumber NSArray消耗的内存是[Float]十倍或更多

  • 尽量避免复制

    如您所见,复制使内存消耗翻倍


首先,重写您的C ++代码。 使用指针而不是vector并避免不必要的复制。

C ++代码:

void CppProcess::cppProcessSwiftArray(const float *arrayOfFloats, int count, float *outputArray) {
    cout << "CPP: Received an array is of size " << count << '\n';

    //For the moment, only create an arbitrary array of same size and return it...
    for(int j=0; j < count; j++){
        outputArray[j] = j ;
    }
}

指针可以轻松地桥接到Swift,因此您的Objective-C代码几乎不需要做什么。

Objective-C代码:

-(void)cppProcessSwiftArray:(const float * _Nonnull)array count:(NSInteger)count output:(float * _Nonnull)outputArray {
    CppProcess cppProcess;
    cppProcess.cppProcessSwiftArray(array, (int)count, outputArray);
}

然后,您可以利用桥接Swift数组和指针的功能。

SWIFT代码:

        let floatArray: [Float] = ...
        var resultArray: [Float] = Array(repeating: 0, count: floatArray.count)
        let objcCppWrapper = ObjcCppWrapper()
        objcCppWrapper.cppProcessSwiftArray(floatArray, count: floatArray.count, output: &resultArray)

谢谢您的回答,它有效。

我也在这里找到了这个“有效”的代码。 但是,您的代码效率更高。 我认为我的代码有问题的一件事是在循环的每次迭代中都复制了NSArray。

NSMutableArray *nsMutableArray = [[NSMutableArray alloc] initWithCapacity: 300000];
for (int i=0; i < 300000; i++) {
    [nsMutableArray insertObject:[NSNumber numberWithFloat:cppArray[i]] atIndex:i];
}

NSArray *returnNsArray = [nsMutableArray copy];
return returnNsArray;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM