我在iOS中实现,所以你可以假设iOS框架可用,如果这有帮助的话.另一方面,简单的C方法(memcmp等)也可以.
注意,我不是要清除内存,而是试图确认它已经很清楚了(我试图找出某些位图数据中是否有任何内容,如果有帮助的话).例如,我认为以下内容可行,但我还没有尝试过:
- BOol data:(unsigned char *)data isNullTolength:(size_t)length { unsigned char tester[length] = {}; memset(tester,length); if (memcmp(tester,data,length) != 0) { return NO; } return YES;}
我宁愿不创建一个测试器阵列,因为源数据可能非常大,我宁愿避免为测试分配内存,即使是暂时的.但我可能在那里过于保守.
更新:一些测试
感谢大家对以下的好评.我决定创建一个测试应用程序,看看它们是如何表现的,答案让我感到惊讶,所以我想我会分享它们.首先,我将向您展示我使用的算法版本(在某些情况下,它们与提议的算法略有不同),然后我将分享该领域的一些结果.
测试
首先,我创建了一些示例数据:
size_t length = 1024 * 768; unsigned char *data = (unsigned char *)calloc(sizeof(unsigned char),(unsigned long)length); int i; int count; long check; int loop = 5000;
每个测试由循环运行循环时间组成.在循环期间,一些随机数据被添加到数据字节流中并从中移除.请注意,实际上没有数据添加的一半时间,因此测试不应该找到任何非零数据的一半时间.请注意,testZeros调用是一个占位符,用于调用下面的测试例程.在循环之前启动计时器并在循环之后停止计时器.
count = 0; for (i=0; i<loop; i++) { int r = random() % length; if (random() % 2) { data[r] = 1; } if (! testZeros(data,length)) { count++; } data[r] = 0; }
测试A:nullTolength.这或多或少是我上面的原始配方,调试和简化了一下.
- (BOol)data:(voID *)data isNullTolength:(size_t)length { voID *tester = (voID *)calloc(sizeof(voID),(unsigned long)length); int test = memcmp(tester,length); free(tester); return (! test);}
测试B:allZero. Carrotman的提案.
BOol allZero (unsigned char *data,size_t length) { bool allZero = true; for (int i = 0; i < length; i++){ if (*data++){ allZero = false; break; } } return allZero;}
测试C:is_all_zero. Lundin提出的建议.
BOol is_all_zero (unsigned char *data,size_t length){ BOol result = TRUE; unsigned char* end = data + length; unsigned char* i; for(i=data; i<end; i++) { if(*i > 0) { result = FALSE; break; } } return result;}
测试D:sumArray.这是vladr提出的nearly duplicate question的最佳答案.
BOol sumArray (unsigned char *data,size_t length) { int sum = 0; for (int i = 0; i < length; ++i) { sum |= data[i]; } return (sum == 0);}
测试E:lulz.史蒂夫杰索普提出的建议.
BOol lulz (unsigned char *data,size_t length) { if (length == 0) return 1; if (*data) return 0; return memcmp(data,data+1,length-1) == 0;}
测试F:NSData.这是一个使用我在iOS SDK中发现的NSData对象的测试,同时处理所有这些.事实证明,Apple确实知道如何比较设计为硬件无关的字节流.
- (BOol)nsdTestData: (NSData *)nsdData length: (NSUInteger)length { voID *tester = (voID *)calloc(sizeof(voID),(unsigned long)length); NSData *nsdTester = [NSData dataWithBytesNocopy:tester length:(NSUInteger)length freeWhenDone:NO]; int test = [nsdData isEqualToData:nsdTester]; free(tester); return (test);}
结果
那么这些方法是如何比较的?这里有两组数据,每组代表5000个循环检查.首先,我在相对较旧的iMac上运行的iPhone模拟器上尝试了这个,然后我尝试在第一代iPad上运行.
在iMac上运行的iPhone 4.3模拟器上:
// Test A,nullTolength: 0.727 seconds// Test F,NSData: 0.727// Test E,lulz: 0.735// Test C,is_all_zero: 7.340// Test B,allZero: 8.736// Test D,sumArray: 13.995
在第一代iPad上:
// Test A,nullTolength: 21.770 seconds// Test F,NSData: 22.184// Test E,lulz: 26.036// Test C,is_all_zero: 54.747// Test B,allZero: 63.185// Test D,sumArray: 84.014
这些只是两个样本,我进行了多次测试,结果略有不同.表现顺序始终如一:A& F非常接近,E就在后面,C,B和D.我会说A,F和E是虚拟联系,在iOS上我更喜欢F,因为它利用了Apple对处理器更改问题的保护,但是A& E非常接近. memcmp方法显然胜过简单的循环方法,在模拟器中接近十倍,在设备本身上快两倍.奇怪的是,D,来自另一个线程的获胜答案在这个测试中表现得很差,可能是因为当它遇到第一个差异时它没有突破循环.
解决方法 不确定它是否是最好的,但我可能会这样做:bool allZero = true;for (int i = 0; i < size_t; i++){ if (*data++){ //Roll back so data points to the non-zero char data--; //Do whatever is needed if it isn't zero. allZero = false; break; }}
如果你刚刚分配了这个内存,你总是可以调用calloc而不是malloc(calloc要求所有数据都被清零). (编辑:在第一篇文章上阅读你的评论,你真的不需要这个.我会留下它以防万一)
总结以上是内存溢出为你收集整理的objective-c – 确保内存区域为空的最快方式(全为NULL)?全部内容,希望文章能够帮你解决objective-c – 确保内存区域为空的最快方式(全为NULL)?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)