gpt4 book ai didi

c++ - 我如何发送(和接收)非常大的 float 数组从 Swift 到 Objective c++ 再到 c++,然后备份到 Swift?

转载 作者:行者123 更新时间:2023-11-28 13:31:56 28 4
gpt4 key购买 nike

我是一名 Swift 程序员,我的 objective-c++ 和 c++ 经验绝不能与我的 Swift 经验相提并论。我已经成功地从 Swift -> Objc++ -> c++(处理发生的地方)发送和接收小型 float 组,然后备份到 Objc++ 和 Swift。我们有大量的工作是用 C++ 执行的,我们暂时不能迁移到 Swift,原因有几个(其中一个原因是 C++ 在完成这项工作时比 Swift 更有效)。

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

以下代码适用于小型数组。但是,对于超过 300,000 的非常大的数组,程序会因为内存问题在 iOS 设备上崩溃,然后在模拟器上下面的 Objective-c++ 代码使用高达 59 GB!

有人可以解释并告诉我一种更好的方法来发送和接收从 Swift 到 Objc++ 再到 C++ 的大型 float 组,然后再返回到 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 来表示原始类型的数组

    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 数组和指针的特性了。

快速代码:

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

关于c++ - 我如何发送(和接收)非常大的 float 数组从 Swift 到 Objective c++ 再到 c++,然后备份到 Swift?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57228532/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com