Pull to refresh

Comments 4

Как мне кажется, проблема в том, что в современный программист вынужден пользоваться высокоуровневыми средствами: языками и библиотеками. Изучить все тонкости происходящего «под капотом» не представляется возможным из-за скорости разработки.
Вот недавно столкнулся: проект использует библиотеки Qt. Все работает.
В классе QImage имеется две похожих функции с одинаковым именем для доступа к пикселям:
uchar * bits()
const uchar * bits() const

Первая, не всегда, но может вызвать «deep copy» — полное копирование пикселей всего изображения в другой буффер. Очень легко по невнимательности или по не знанию пропустить этот факт. Вот и получается — все вроде бы правильно и работает, но что-то где-то тормозит.

Старые добрые грабли с COW. Dinkumware уже на них наступали…
Что-то где-то тормозит, а что-то где-то и падает с грохотом!

QImage a;
// как-то его проинициализировали...
...
QImage b = a;  // спровоцировали совместное владение
const QImage& c = b;
for (const uchar *p = c.bits(), *end = c.bits() + c.byteCount(); p != end; ++p) {
  // сделали безобидное (казалось бы) действие.
  const uchar* q = b.bits(); // спровоцировали COW, - хотя Write ещё нет, но мы же не можем более уследить.

  a = QImage();  // освободили старую память
  // начиная с этого места, указатель p невалидный

  do_smth(*p);
}

Хуже всего, когда разрабу говорят — приложение же работает? Ну и сдаем, какая еще оптимизация.

Потом имеем байки про "… и в продакшен".

И хорошо, когда есть настойчивость сделать хорошо, а потом — еще лучше. И не сказать, что железо все вытерпит, а именно взять и сделать.

А что будет с этой оптимизацией в программе, которая мечтала запустить по потоку на всех четырех физических ядрах, но вместо этого оказалась запущенной под Ruby, который был собран без поддержки потоков ОС?

Sign up to leave a comment.