Tôi vừa mới bắt đầu với C và có rất ít kiến thức về các vấn đề về hiệu suất với malloc()
và free()
. Câu hỏi của tôi là: nếu tôi được gọi malloc()
, theo sau là free()
bên trong vòng lặp while
lặp lại 20 vòng lặp, nó sẽ chạy chậm hơn so với gọi số free()
bên ngoài vòng lặp? Tôi thực sự đang sử dụng phương pháp đầu tiên để cấp phát bộ nhớ cho một bộ đệm, đọc một chuỗi có độ dài biến đổi từ một tệp, thực hiện một số thao tác chuỗi và sau đó xóa bộ đệm sau mỗi lần lặp lại. Nếu phương pháp của tôi dẫn đến rất nhiều chi phí thì tôi muốn yêu cầu một cách tốt hơn để tôi đạt được kết quả tương tự.Lập trình C: malloc và miễn phí trong vòng một
Trả lời
Chắc chắn chậm hơn. (Nhưng hãy nhớ rằng bạn cần cân bằng số lượng malloc
và free
nếu không bạn bị rò rỉ bộ nhớ.)
Nếu chiều dài thay đổi, bạn có thể sử dụng realloc
để mở rộng kích thước bộ đệm.
void* v = malloc(1024);
size_t bufsize = 1024;
while(cond) {
size_t reqbufsize = get_length();
if (reqbufsize > bufsize) {
bufsize = reqbufsize * 2;
v = realloc(v, bufsize);
}
// you may shrink it also.
do_something_with_buffer(v);
}
free(v);
+1 - nhưng bạn không nghĩ rằng 'bufsize = reqbufsize * 2;' là một chút quyết liệt? : P –
Có thể. Việc thực thi MSVC2k8 của 'std :: vector' tăng bộ đệm của nó lên 150% khi tái phân bổ. –
@ BillyONeal: Đó thực sự là một cách khá phổ biến để làm mọi thứ. – Dinah
Nếu bạn biết độ dài tối đa của bộ đệm - hoặc có thể đặt mức tối đa hợp lý - thì bạn có thể sử dụng cùng một bộ đệm cho mỗi lần lặp lại. Nếu không những gì bạn đang làm sẽ ổn thôi.
Nó phụ thuộc vào việc triển khai malloc và miễn phí.
Cách tốt nhất để trả lời câu hỏi của bạn là tạo điểm chuẩn ...
Tùy thuộc vào những gì bạn cần bộ đệm.
Bạn có thực sự cần phải xóa nó sau mỗi lần lặp lại hoặc có thể là \0
char ở cuối sẽ đủ để đánh dấu sự kết thúc của một chuỗi? Sau khi tất cả những gì mà các cuộc gọi thư viện str
khác nhau sử dụng.
Nếu bạn thực sự cần xóa nó, bạn có thể sử dụng bzero()
. Chắc chắn malloc'ing và free'ing tại mỗi iteration là một sự lãng phí tài nguyên, vì bạn hạnh phúc có thể tái sử dụng bộ đệm.
Một vấn đề khác sẽ phát sinh nếu bạn song song vòng lặp for, tức là có một số luồng đồng thời sử dụng nó.
Ví dụ đơn giản, thực tế: sử dụng xô để mang nước. Giả sử bạn cần thực hiện một số chuyến đi với nhóm đó: bạn có muốn nhặt nó lên, sử dụng nó, đặt nó xuống, nhặt nó lên lần nữa, sử dụng nó, v.v ...? Bạn có thể tái sử dụng thùng nhiều lần nhất có thể. Nếu, mặt khác, nhóm cần phải được bạn và nhiều người sử dụng, hoặc bạn tổ chức truy cập vào thùng hoặc cần nhiều nhóm hơn.
Đề xuất cuối cùng: đừng lo lắng về buổi biểu diễn ngay bây giờ. Họ nói rằng tối ưu hóa sớm là gốc rễ của tất cả các điều ác, và bạn sẽ sớm hiểu tại sao.
Thứ nhất, hãy hiểu vấn đề: viết mã có thể bị vứt bỏ. Thí nghiệm. Thứ hai, kiểm tra nó. Hãy chắc chắn rằng nó làm những gì bạn cần. Thứ ba, tối ưu hóa nó. Làm cho vòng lặp chạy mười nghìn lần và đo thời gian cần thiết. Sau đó di chuyển malloc bên ngoài, và đo lại (sử dụng lệnh shell time
nếu theo UNIX). Thứ tư, viết lại nó bởi vì thử nghiệm đầu tiên của bạn rất có thể sẽ là một mớ hỗn độn của các bản thử lại không hoạt động.
Rửa sạch, lặp lại.
ps: vui chơi trong thời gian trung bình. Nó được cho là thú vị, không bực bội.
Thường thì mọi thứ có thể di chuyển ra ngoài vòng lặp phải là. Tại sao lặp lại cùng một hành động khi bạn chỉ có thể làm điều đó một lần?
Justin Ethier là đúng, phân bổ bộ đệm phù hợp thoải mái với chuỗi lớn nhất và tái sử dụng.
Trong 20 lần lặp lại, bạn không nên lo lắng về hiệu suất của malloc/miễn phí.
Thậm chí đối với nhiều thứ hơn (một vài đơn vị độ lớn), bạn không nên bắt đầu suy nghĩ về tối ưu hóa cho đến khi bạn cấu hình mã và hiểu những gì đang chậm.
Cuối cùng, nếu bạn định giải phóng bộ đệm, không cần phải xóa bộ đệm trước. Ngay cả khi bạn đã di chuyển malloc/miễn phí bên ngoài vòng lặp (sử dụng bộ đệm tối đa theo đề xuất của Justin), bạn không cần phải xóa bộ đệm một cách rõ ràng.
Bạn không thể gọi miễn phí bên ngoài vòng lặp nếu bạn đang gọi malloc bên:
char * buffer;
for (int i = 0; i < num_files; i++) {
buffer = malloc(proper_length(i));
// do some things with buffer
}
free(buffer);
Bạn sẽ malloc'ed num_files
lần, nhưng chỉ giải phóng một lần - bạn bị rò rỉ bộ nhớ từ khắp nơi nhưng cuối cùng !
Có hai lựa chọn chính - malloc trước khi vòng lặp (hoặc chỉ cần sử dụng một mảng) nếu bạn biết một kích thước mà sẽ làm việc cho tất cả mọi thứ, hoặc sử dụng realloc:
char * buffer = NULL;
for (int i = 0; i < num_files; i++) {
buffer = realloc(proper_length(i));
// do some things with buffer
}
free(buffer);
Process nó tốt hơn. Có một số mã giả:
#define BLOCK_SIZE 1024 // or about the bigger size of your strings.
char *buffer = (char *) malloc(BLOCK_SIZE)
for(int i=0; i<20; i++)
{
while (more bytes left to read)
{
read full string or BLOCK_SIZE bytes at max // most calls work this way
proces bytes in buffer
}
}
free(buffer);
- 1. Malloc, miễn phí và phân đoạn lỗi
- 2. Visual C++ thread an toàn miễn phí và malloc?
- 3. Có cách nào để giảm ostocstream malloc/miễn phí?
- 4. LD_PRELOAD chỉ hoạt động đối với malloc, không miễn phí
- 5. miễn phí không gian được phân bổ trong c với malloc
- 6. Làm thế nào xấu nó là để giữ gọi malloc() và miễn phí()?
- 7. Khóa ngăn xếp và xếp hàng miễn phí trong C#
- 8. Trình xem PDF miễn phí trong ASP.net
- 9. miễn phí con trỏ char trong c
- 10. C - Thiết kế miễn phí của riêng bạn() chức năng
- 11. Tìm một cổng miễn phí
- 12. sự điên rồ là miễn phí()
- 13. Tại sao sử dụng malloc/miễn phí, khi chúng tôi có mới/xóa?
- 14. Thư viện mã hóa miễn phí C++
- 15. Trình định dạng mã miễn phí và tốt
- 16. miễn phí() gọi công trình trên giả lập, làm cho iPad tức giận. iPad smash
- 17. Giữ các trường hợp miễn phí EC2 Miễn phí
- 18. Trình biên dịch Java AOT miễn phí
- 19. Trình gỡ rối JavaScript miễn phí?
- 20. gửi SMS miễn phí từ C# + ASP.NET
- 21. MinGW không xác định tham chiếu đến malloc, miễn phí, sprintf, _beginthreadex
- 22. "Biến miễn phí" là gì?
- 23. Chương trình chia sẻ màn hình tốt, miễn phí cho lập trình ghép nối?
- 24. C: Gọi miễn phí trên một biến tự động?
- 25. Có một trình thiết kế Java GUI miễn phí không?
- 26. Cầu miễn phí
- 27. miễn phí() trên bộ nhớ ngăn xếp
- 28. Tại sao tôi không gặp lỗi liên kết khi tôi cung cấp malloc của riêng mình và miễn phí?
- 29. Sự khác biệt giữa việc sử dụng realloc vs miễn phí - chức năng> chức năng malloc
- 30. Có thể miễn phí 'void *' không?
Bạn không thể gọi miễn phí bên ngoài vòng lặp nếu bạn đang gọi malloc bên trong nó hoặc bạn sẽ tiết lộ bộ nhớ cho tất cả trừ malloc từ lần lặp cuối cùng. Bạn có thể, tuy nhiên, sử dụng realloc thay vì malloc, sau đó miễn phí bên ngoài. – Cascabel
@ Jefromi: Tôi nghĩ bạn nên đưa ra nhận xét đó một câu trả lời. –
Tiếng Anh của bạn là tốt - nó tốt hơn trong thực tế hơn so với hầu hết người mới của tiếng Anh trên SO. –