calloc v / s malloc и эффективность по времени - PullRequest
13 голосов
/ 09 апреля 2010

Я с интересом прочитал сообщение C разница между malloc и calloc . Я использую malloc в своем коде и хотел бы знать, какая разница будет при использовании calloc.

Мой настоящий (псевдо) код с malloc:

Сценарий 1

int main()
{  
   allocate large arrays with malloc

   INITIALIZE ALL ARRAY ELEMENTS TO ZERO

   for loop //say 1000 times
    do something and write results to arrays
   end for loop

   FREE ARRAYS with free command

} //end main

Если я использую calloc вместо malloc, тогда у меня будет:

Scenario2

int main()
{  

   for loop //say 1000 times
    ALLOCATION OF ARRAYS WITH CALLOC 

    do something and write results to arrays

    FREE ARRAYS with free command

   end for loop


} //end main

У меня три вопроса:

  1. Какой из сценариев более эффективен, если массивы очень большие?

  2. Какой из сценариев будет более эффективным по времени, если массивы очень большие?

  3. В обоих сценариях я просто пишу в массивы в том смысле, что для любой данной итерации в цикле for я записываю каждый массив последовательно от первого элемента до последнего элемента. Важный вопрос: если я использую malloc, как в сценарии 1, то необходимо ли инициализировать элементы нулями? Скажем, с malloc у меня есть массив z = [garbage1, garbage2, garbage 3]. Для каждой итерации я пишу элементы последовательно, т.е. в первой итерации я получаю z = [some_result, garbage2, garbage3], во второй итерации я получаю в первой итерации я получаю z = [some_result, another_result, garbage3] и так затем мне нужно специально инициализировать мои массивы после malloc?

Ответы [ 6 ]

11 голосов
/ 09 апреля 2010

Если предположить, что общий объем памяти, инициализируемый в ваших двух примерах, одинаков, выделение памяти с помощью calloc() может быть быстрее, чем выделение памяти с помощью malloc(), а затем обнуление их на отдельном шаге, особенно если в в случае malloc() вы обнуляете элементы индивидуально, повторяя их в цикле. malloc(), за которым следует memset(), вероятно, будет примерно таким же быстрым, как calloc().

Если вам не важно, что элементы массива являются мусором до того, как вы на самом деле сохраните в них результаты вычислений, нет необходимости фактически инициализировать ваши массивы после malloc().

1 голос
/ 09 апреля 2010

Для 1 и 2 оба делают одно и то же: выделяют и обнуляют, затем используют массивы.

Для 3, если вам не нужно сначала обнулять массивы, то обнуление не нужно и не делать это быстрее.

Существует вероятность, что обнуление calloc более эффективно, чем код, который вы пишете, но эта разница будет небольшой по сравнению с остальной частью работы программы. Реальная экономия calloc не в том, чтобы писать этот код самостоятельно.

0 голосов
/ 31 мая 2018

malloc быстрее, чем Calloc, потому что причина в том, что malloc возвращает память в том виде, как она есть в операционной системе. Но когда вы вызываете Calloc, он получает память от ядра или операционной системы и инициализирует ее нулем, а затем возвращает вам. Итак, инициализация занимает время. Вот почему Malloc быстрее, чем Calloc

0 голосов
/ 13 марта 2013

malloc отличаются на calloc по двум причинам

  1. malloc принимает один аргумент, тогда как calloc принимает два аргумента

  2. malloc быстрее, чем calloc. Причина в том, что malloc обрабатывает одномерный массив в формат указателя, тогда как calloc принимает двухмерный массив и перед обработкой преобразуется в одномерный массив, а затем в формат указателя.

Я думаю, именно поэтому malloc обрабатывает быстрее, чем calloc

0 голосов
/ 09 апреля 2010

Ваша точка, указанная в 3., кажется, указывает на случай или ненужную инициализацию. Это довольно плохо с точки зрения скорости, тратится не только время, потраченное на его выполнение, но и из-за этого происходит большое вытеснение кеша.

Выполнение memset() или bzero() (которые в любом случае вызываются calloc()) - хороший способ аннулировать огромную часть вашего кэша. Не делайте этого, если вы не уверены, что не будете перезаписывать все, но можете прочитать части буфера, которые не будут записаны (как будто 0 является приемлемым значением по умолчанию) Если вы все равно все переписываете, не инициализируйте свою память без необходимости.

Ненужная запись в память не только ухудшит производительность вашего приложения, но и производительность всех приложений, совместно использующих один и тот же процессор.

0 голосов
/ 09 апреля 2010

Подходы calloc и memset должны быть примерно одинаковыми и, возможно, немного быстрее, чем обнулять их самостоятельно.

Независимо от того, все это связано с тем, что вы делаете внутри своего основного цикла, который может быть на несколько порядков больше.

...