内存占用优化和性能

时间:2013-12-05 01:29:21

标签: c string memory c99

我对我的C99应用程序的内存占用感到担忧,它会加载很多字符串。我有字符串长度的上限,我基本上做这样的事情(这个语句在循环中):

char* input = (char*)malloc(sizeof (char)* MAX_CHAR_INPUT_SIZE);
scanf_s("%s", input, MAX_CHAR_INPUT_SIZE);

正如您所看到的,如果用户提供的字符串很小,则浪费了大量内存。我唯一的想法是在读取之后将该字符串复制到大小合适的内存块,然后释放更大的内存。这是好方法吗? (我知道它将是O(N))。

也有人可以向我解释这是如何在高级语言中解决的吗? (例如C#的Console.Read())

2 个答案:

答案 0 :(得分:1)

你应该考虑的一件事是,与memcpy()相比,malloc()是一个非常昂贵的函数,特别是在涉及并发时。高性能程序中更常见的策略之一是在线程本地存储中实际预先分配尽可能多的缓冲区内存,然后实际复制这些缓冲区之间的数据(包括字符串)以最小化需要的共享状态量保护。

这很有效,因为CPU具有大量廉价的计算资源,并且经过优化可有效地移动数据。这与数据访问同步方案相反,在现代系统中,这种方案非常复杂(涉及多级缓存层次结构的多个核心),因此速度很慢。

“托管内存”环境也是如此,例如JVM和CLR(使用任何语言)。查看有关高性能Java交易系统的文章(方法是相同的:预分配内存然后进行大量复制以最小化共享状态):http://martinfowler.com/articles/lmax.html

而且,与往常一样,任何编程技巧和模式都不应该热心。很容易过度复制到这样的程度,以使完美的程序令人难以置信地缓慢(或不必要地消耗太多的内存)。广泛的基准测试是绝对必要的。

答案 1 :(得分:1)

如果您在循环中执行此操作,则可以在为最终字符串分配内存之前将其读入临时文件:

char input[MAX_CHAR_INPUT_SIZE];

scanf_s("%s", input, sizeof input);

size_t input_size = strlen(input) + 1;
char *input_final = malloc(input_size);
memcpy(input_final, input, input_size);

这样,每个字符串仍然只能调用malloc(),但每次都会分配完全正确的大小。