Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_GНа чистом CНа чистом C это так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. Спасибо за ответ. Вы тоже используете функци strcat , вот я не могу понять, почему у меня не получалось. Сейчас буду думать, чем мой вариант отличается. И у меня паралельный вопрос появился - вы создаете структуру и сразу определяете максимальное количество элементов в свойствах. Я создаю структуру с указателями, и потом в коде сколько мне понадобиться символов, столько я и создам, а потом скопирую указатель на массив. Чем такой подход плох? Спасибо! Если заранее определить максимальное количество элементов (как у меня задать массив), то все 3 массива структуры будут лежать рядом, и если затем создать массив структур struct videoShop object2[1000000]; то все структуры и все их элементы будут лежать рядом в памяти, и доступ будет значительно быстрее. Если использовать strdup() или malloc(), то указатели будут в одном месте рядом, а выделенные строки разбросаны в памяти, что замедлит к ним доступ. Помимо этого нужно будет будет освобождать память используя free(), чтобы не было утечек памяти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 20:55 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovНа чистом Cвполне достаточно \0 в конце каждой строки. А что, без этого там терминаторов не будет?.. Будут конечно :) Явное использование \0 в строках - бессмысленно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 20:57 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На чистом Cдоступ будет значительно быстрее. Прежде чем оптимизировать, посмотрите на предметную область. Никого не интересует скорость когда речь фактически идет про базу данных. Тем более что никакого "значительно быстрее" не будет. Максимум доли процента. Т.к. типичная программа такого рода однопоточная и никаких конкрурентных обращений к куче не будет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:01 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyТем более что никакого "значительно быстрее" не будет. Максимум доли процента. А в замен вы вводите лимит на размеры данных, о котором никто не просил, а также накладные расходы по хранению больших массивов с запасом, хотя типичные данные в несколько раз меньше размером. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:08 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyНа чистом Cдоступ будет значительно быстрее. Прежде чем оптимизировать, посмотрите на предметную область. Никого не интересует скорость когда речь фактически идет про базу данных. Тем более что никакого "значительно быстрее" не будет. Максимум доли процента. Т.к. типичная программа такого рода однопоточная и никаких конкрурентных обращений к куче не будет. Префетчем можно будет достать в L3/L2 весь массив структур, а в случае с динамической вытащим только указатели, а каждый элемент - 300 тактов задержки на обращение к RAM. Использование чистого C, как бы намекает на необходимость в скорости. Оптимизировать все подряд конечно не надо, но использование статического массива, вместо динамического - это и быстрее, и удобней без необходимости выделения, освобождения и проверки на NULL перед использованием. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:09 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyAnatoly MoskovskyТем более что никакого "значительно быстрее" не будет. Максимум доли процента. А в замен вы вводите лимит на размеры данных, о котором никто не просил, а также накладные расходы по хранению больших массивов с запасом, хотя типичные данные в несколько раз меньше размером. А проблемы динамической памяти: утечки памяти, обращение к невыделенной/освобожденной памяти, время на выделение/освобождение, накладные расходы на дефрагментацию и хранение в куче. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:12 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На чистом CПрефетчем можно будет достать в L3/L2 весь массив структур, а в случае с динамической вытащим только указатели, а каждый элемент - 300 тактов задержки на обращение к RAM. Максимум доли процента выигрыша. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:13 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На чистом CА проблемы динамической памяти: утечки памяти, обращение к невыделенной/освобожденной памяти Только утечки. Но на то и С++ и std::string, чтобы не заботиться об этом. Обращение к невыделенной/освобожденной памяти - это касается и массивов, только там будет неинициализированная память. Про скорость - уже сказал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:19 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyНа чистом CПрефетчем можно будет достать в L3/L2 весь массив структур, а в случае с динамической вытащим только указатели, а каждый элемент - 300 тактов задержки на обращение к RAM. Максимум доли процента выигрыша. Смотря какая задача. Непосредственно в этом месте: 1. для статического: 100нс латентности + (1000000 элементов * 150 байт / 40 ГБ/c) = 100 + 4000000 = 4 мс. 2. для динамеческого: 100нс * 1000000 э + (1000000 элементов * 150 байт / 40 ГБ/c) = 104 мс. Учитываем, что в случае динамического может многократно освобождаться/выделяться память под новый размер строки, тем самым дефрагментируя память. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:21 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Точнее фрагментируя :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:21 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyНа чистом CА проблемы динамической памяти: утечки памяти, обращение к невыделенной/освобожденной памяти Только утечки. Но на то и С++ и std::string, чтобы не заботиться об этом. Обращение к невыделенной/освобожденной памяти - это касается и массивов, только там будет неинициализированная память. Про скорость - уже сказал. Автор пока явно пишет на C и strcat. С одним массивом это несколько несколько легче, чем с миллионом его элементов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:25 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На чистом CСмотря какая задача. Непосредственно в этом месте: 1. для статического: 100нс латентности + (1000000 элементов * 150 байт / 40 ГБ/c) = 100 + 4000000 = 4 мс. 2. для динамеческого: 100нс * 1000000 э + (1000000 элементов * 150 байт / 40 ГБ/c) = 104 мс. Так я и сказал, что для этой конкретной задачи никакого выигрыша не будет. Я не про все задачи говорил. В большинстве задач, выборка такого размера означает работу с файлом или БД. И там операции с таким кол-вом элементов имеют существенно большее время, чем сотни мс, да и применяются совсем другие принципы хранения данных чем линейный массив в памяти. Вообще наиболее вероятные классы задач где надо оптимизировать доступ к куче - это вычисление матриц и низкоуровневые библиотеки управления ппамятью. Во всех остальных случаях - такая оптимизация скорее всего бессмысленна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:38 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyНа чистом CСмотря какая задача. Непосредственно в этом месте: 1. для статического: 100нс латентности + (1000000 элементов * 150 байт / 40 ГБ/c) = 100 + 4000000 = 4 мс. 2. для динамеческого: 100нс * 1000000 э + (1000000 элементов * 150 байт / 40 ГБ/c) = 104 мс. Так я и сказал, что для этой конкретной задачи никакого выигрыша не будет. Я не про все задачи говорил. В большинстве задач, выборка такого размера означает работу с файлом или БД. И там операции с таким кол-вом элементов имеют существенно большее время, чем сотни мс, да и применяются совсем другие принципы хранения данных чем линейный массив в памяти. Вообще наиболее вероятные классы задач где надо оптимизировать доступ к куче - это вычисление матриц и низкоуровневые библиотеки управления ппамятью. Во всех остальных случаях - такая оптимизация скорее всего бессмысленна. Ничего себе не будет, 100% * 104/4 = 2600%, в 26 раз:) Считайте, что СУБД закэшировала эти 150 МБ данных ;) Там где нужен обход большого количества элементов, а это аналитика, применяют блоки/страницы БД размером порядка 1 МБ, выделенный одним куском в памяти, но уж точно не выделяют память на каждый элемент по 20-50 байт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 21:51 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На чистом CНичего себе не будет, 100% * 104/4 = 2600%, в 26 раз:) Реальных задач где вы будете иметь такой выигрыш - нет. В жизни все сложнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 22:10 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
кстати, использование функций strcpy, strcat, sprintf в C/C++ очень не рекомендуется. Для ядра Linux даже писали утилиту которая находит все случаи использованоя, чтобы удалить. всегда пользуйтесь версиями с буквой 'n' в середине, для контроля размеров. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2012, 02:21 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На чистом CПрефетчем можно будет достать в L3/L2 весь массив структур, а в случае с динамической вытащим только указатели, а каждый элемент - 300 тактов задержки на обращение к RAM. Использование чистого C, как бы намекает на необходимость в скорости. Оптимизировать все подряд конечно не надо, но использование статического массива, вместо динамического - это и быстрее, и удобней без необходимости выделения, освобождения и проверки на NULL перед использованием. А почему 300 тактов? Ведь за один раз сразу будем получать одну структуру, не по одному же элементу будем тянуть. То есть, выигрыш представляется в три раза. Не три структуры за один раз, а только одну. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2012, 03:32 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
YathaНа чистом CПрефетчем можно будет достать в L3/L2 весь массив структур, а в случае с динамической вытащим только указатели, а каждый элемент - 300 тактов задержки на обращение к RAM. Использование чистого C, как бы намекает на необходимость в скорости. Оптимизировать все подряд конечно не надо, но использование статического массива, вместо динамического - это и быстрее, и удобней без необходимости выделения, освобождения и проверки на NULL перед использованием. А почему 300 тактов? Ведь за один раз сразу будем получать одну структуру, не по одному же элементу будем тянуть. То есть, выигрыш представляется в три раза. Не три структуры за один раз, а только одну. У Anatoly Moskovsky память выделяется под каждый элемент, а не под структуру. Во-первых с префетчем структуры будем получать сразу все 1000000 в обоих случаях. Во-вторых с динамическим выделением памяти под каждый элемент , в структуре хранятся только указатели , и за каждым элементом будем обращаться в кучу отдельно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2012, 14:20 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На чистом C, Давайте перестанем теоретизировать и померяемся померяем время работы в обоих случаях для какой-нибудь операции над массивом. Например возьмем самое простое создание, заполнение и удаление массива. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. результат2S1: 00:00:00.498765 2S2: 00:00:00.714403 2S1: 00:00:00.556077 2S2: 00:00:00.791637 (CPU Intel Core I3 330M) Мы видим что никаких 36 раз нет. И это я взял только самое примитивное. Разница видна только потому что sprintf сравним по времения с созданием и копированием одной записи. А как только добавится какая-то нетривиальная обработка каждой записи (например если вы будете фетчить записи из курсора БД), то разница уже будет неощутима . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2012, 15:17 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyА как только добавится какая-то нетривиальная обработка каждой записи (например если вы будете фетчить записи из курсора БД), то разница уже будет неощутима . В случае S1 данные уже в формате хранения на диске. Достаточно сделать mmap файла и все данные доступны. в случае S2 их нужно каким то образом загружать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2012, 16:34 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
OoCcВ случае S1 данные уже в формате хранения на диске. Достаточно сделать mmap файла и все данные доступны. в случае S2 их нужно каким то образом загружать. Ну я ж просил, без сферических массивов в вакууме. Посчитайте сколько по времени займет загрузка с диска в память 150МБ файла . И потом посчитайте, сколько сколько из 150 байтов на запись в среднем будет использовано на полезные данные. И потом подумайте чей вклад в скорость будет выше - доступа к диску или к памяти. Проблема в том что тут предлагается рассматривать скорость отдельных низкоуровневых операций, а надо рассматривать скорость алгоритма в целом. Можно построить быстрый алгоритм на медленных операциях, а можно медленный - на быстрых. Кроме того, до какого-то значения задержек скорость может быть вообще не важна (если юзер не замечает задержек). Поэтому не зная алгоритма закладывать в структуры данных существенные ограничения в целях мифической оптимизации - бессмысленно, и даже вредно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2012, 17:14 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, согласен, все сильно зависит от конкретной задачи. возвращаясь к вашему тесту. поведение аллокатора памяти разное в процессе с одной нитью и несколькими. прогоните ваш тест как нибудь так Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. и результат будет несколько другой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2012, 20:51 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovskyрезультат2S1: 00:00:00.498765 2S2: 00:00:00.714403 2S1: 00:00:00.556077 2S2: 00:00:00.791637 (CPU Intel Core I3 330M) Мы видим что никаких 36 раз нет. И это я взял только самое примитивное. Разница видна только потому что sprintf сравним по времения с созданием и копированием одной записи. А как только добавится какая-то нетривиальная обработка каждой записи (например если вы будете фетчить записи из курсора БД), то разница уже будет неощутима . В тесте не учитывается возможность многопоточной работы и фрагментации памяти. Ясно, что у вас в куче они разложились последовательно и моментально закэшировались. Создал консольный проект в MSVS 2010: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. авторstruct S1: 00:00:00.992057 struct S2: 00:01:04.066665 struct S1: 00:00:01.001057 struct S2: 00:01:04.163670 (CPU Intel Core I5 K750) В 64 раза. И это без учета фрагментации. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2012, 22:47 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Убрал бустовый замер и оставил clock();. Сделал фрагментацию прыгая с шагом 10000 объектов = 1.5 МБ. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. заполнение через тормозной sprintf: авторstruct S1: 1026 struct S2: 172125 struct S1: 1024 struct S2: 173539 В 173 раза. заполнение через быстрый strcpy: авторstruct S1: 139 struct S2: 125346 struct S1: 137 struct S2: 128770 В 920 раз. Вот это с фрагментацией и видимо многопоточным вариантом malloc/new. Плюс оверхед на динамической памяти на каждый элемент: 8 байт на указатель + 8 байт на размер + сколько-то в среднем на вырванивание. В сумме 20 байт оверхеда минимум на каждый элемент, плюс 20 байт допустим в среднем строка, итого 40 против 50 - вот и вся экономия :) Если строка в срденем не 20, а 10, то и в статическом делаем не 50, а 25 и даже выигрываем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2012, 23:30 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Microsoft Visual Studio 2010 Версия 10.0.40219.1 SP1Rel Microsoft Visual C++ 2010 Выставлено: Maximize Speed (/O2) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2012, 00:05 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На C/C++Microsoft Visual Studio 2010 Версия 10.0.40219.1 SP1Rel Microsoft Visual C++ 2010 Выставлено: Maximize Speed (/O2) вот и пользуйся после таких результатов виндой. теперь понятно почему C# такой тормозной. $ uname -s -r Linux 3.6.6-1.fc17.x86_64 $ cat /proc/cpuinfo | grep "model name" model name : Intel(R) Core(TM)2 CPU 6300 @ 1.86GHz model name : Intel(R) Core(TM)2 CPU 6300 @ 1.86GHz $ g++ --version g++ (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2) no optimization strcpy : автор2S1: 200381 microseconds 2S2: 602437 microseconds 2S1: 495252 microseconds 2S2: 856197 microseconds sprintf : автор2S1: 712078 microseconds 2S2: 1114774 microseconds 2S1: 1108407 microseconds 2S2: 1458388 microseconds threaded strcpy автор2S1: 207335 microseconds 2S2: 908294 microseconds 2S1: 511827 microseconds 2S2: 1142337 microseconds sprintf автор2S1: 706403 microseconds 2S2: 1420363 microseconds 2S1: 1146519 microseconds 2S2: 1737317 microseconds итого 1.3 - 4.5 раза разница. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2012, 00:50 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38043498&tid=2020661]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
180ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
| others: | 16ms |
| total: | 295ms |

| 0 / 0 |
