Как я могу отправлять (и получать) чрезвычайно большие плавающие массивы из Swift в Objective c ++ в c ++, а затем выполнять резервное копирование в Swift?

АсокаТано

Я программист на Swift, мой опыт в области Objective-C ++ и C ++ НИКОГДА не соответствует моему опыту в Swift. Мне удалось отправить и получить небольшие массивы чисел с плавающей запятой из Swift -> Objc ++ -> c ++ (где происходит обработка), а затем обратно в Objc ++ и Swift. У нас есть большой объем работы, выполняемой на C ++, которую мы на данный момент не можем перейти на Swift по нескольким причинам (одна из которых C ++ намного эффективнее выполняет эту работу, чем Swift).

Программа на C ++ выполняет работу с чрезвычайно большими массивами чисел с плавающей запятой. В настоящий момент эти массивы чисел с плавающей запятой отправляются и используются программой C ++ в виде файлов CSV. Мы хотим покончить с этими CSV-файлами, чтобы исключить необходимость чтения и записи на диск. Мы хотели бы иметь дело непосредственно с массивами чисел с плавающей запятой.

Следующий код хорошо работает с небольшими массивами. Но с очень большими массивами из 300000+ программа просто вылетает на устройстве iOS из-за проблем с памятью, а затем на симуляторе приведенный ниже код Objective-c ++ использует до 59 ГБ!

Может ли кто-нибудь объяснить и подсказать мне лучший подход к отправке и получению больших массивов чисел с плавающей запятой из 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по значению? Лучше использовать ссылку, чтобы избежать копирования.

В любом случае, если вы думаете об эффективности памяти, лучше позаботьтесь о двух вещах:

  • Никогда не используйте NSArrayдля представления массива примитивного типа

    NSArrayиз NSNumberпотребляет в десять раз или больше памяти , чем[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 мало что нужно делать.

Код цели-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)

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

TOP Lista

CalienteEtiquetas

Archivo