簡體   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