psilogic: (Default)
psilogic ([personal profile] psilogic) wrote2011-04-05 03:19 pm

Программерам

Задачка: как оптимизировать такой код, чтобы убрать копи-пасты?
Напрашивается заведение двух функций... а, может, кто-нибудь знает другие трюки?


if (undoCase)
{
	if (op & OpBefore)
	{
		uf.read(&hb, sizeof(hb));
		*hNew= hb;
		++hNew;
		++i;
	}
	if (op & OpAfter)
	{
		uf.seek(sizeof(GHarmonicBase), SEEK_CUR);//pass redo data
		++hOld;
	}
}
else
{
	if (op & OpBefore)
	{
		uf.seek(sizeof(GHarmonicBase), SEEK_CUR);//pass undo data
		++hOld;
	}
	if (op & OpAfter)
	{
		uf.read(&hb, sizeof(hb));
		*hNew= hb;
		++hNew;
		++i;
	}
}


Upd: Порядок вызова seek/read важен - там в файле два последовательных блока, наличие/отсутствие которых определяется флагами OpAfter/OpBefore.

[identity profile] lionet.livejournal.com 2011-04-05 11:27 am (UTC)(link)
if(!((op & opBefore) ^ undoCase) && !(op & opAfter)) {
uf.read(&hb, sizeof(hb));
*hNew= hb;
++hNew;
++i;
}
if(!((op & opAfter) ^ undoCase) && !(op & opBefore)) {
uf.seek(sizeof(GHarmonicBase), SEEK_CUR);//pass undo data
++hOld;
}

[identity profile] lionet.livejournal.com 2011-04-05 11:28 am (UTC)(link)
Это псевдокод, вестимо.

[identity profile] psilogic.livejournal.com 2011-04-05 11:30 am (UTC)(link)
порядок seek/read важен :)

[identity profile] 3seemingmonkeys.livejournal.com 2011-04-05 11:47 am (UTC)(link)
както так может

bef = op & opBefore
aft = op & opAfter
if (undoCase & bef | !undoCase & aft)
{
uf.read(&hb, sizeof(hb));
*hNew= hb;
++hNew;
++i;
}
else
{
uf.seek(sizeof(GHarmonicBase), SEEK_CUR);//pass redo data
++hOld;
}

[identity profile] afa-at-work.livejournal.com 2011-04-05 11:50 am (UTC)(link)
вынос в методы. и не заморачиваться.

[identity profile] http://users.livejournal.com/_stilgar/ 2011-04-05 11:53 am (UTC)(link)
Вывод в методы, или языческое goto

[identity profile] psilogic.livejournal.com 2011-04-05 12:01 pm (UTC)(link)
О! Насчет языческого я и забыл... :)

[identity profile] psilogic.livejournal.com 2011-04-05 12:02 pm (UTC)(link)
для файла seek, read не равно read, seek

[identity profile] psilogic.livejournal.com 2011-04-05 12:03 pm (UTC)(link)
На практике - да, но можно рассмотерть как "олимпиадную задачку"...

[identity profile] racoonbear.livejournal.com 2011-04-05 12:14 pm (UTC)(link)
Ты не указал цель оптимизации - уменьшить зависимость от условных переходов, или увеличить скорость, или уменьшить количество строк кода \ вызовов, или улучшить читаемость или...

[identity profile] psilogic.livejournal.com 2011-04-05 12:18 pm (UTC)(link)
Убрать дублирующий код, не увеличивая общий объем кода.

[identity profile] 3seemingmonkeys.livejournal.com 2011-04-05 12:19 pm (UTC)(link)
выходит надо выполнить
seek
read

или

read
seek

тут или копипаста или goto третьего не дано имхо.

[identity profile] psilogic.livejournal.com 2011-04-05 12:21 pm (UTC)(link)
похоже на то

[identity profile] afa-at-work.livejournal.com 2011-04-05 12:30 pm (UTC)(link)
один фиг достаточно. дальнейшая - читабельность ухудшит и сильно.

[identity profile] 3seemingmonkeys.livejournal.com 2011-04-05 12:35 pm (UTC)(link)
можно убрать 1 дубль :)

if (s = !u & bef) {
seek
}
read;
if (!s) {
seek;
}

[identity profile] psilogic.livejournal.com 2011-04-05 12:37 pm (UTC)(link)
неплохо!

[identity profile] racoonbear.livejournal.com 2011-04-05 12:38 pm (UTC)(link)
звучит как подмена цели средством

[identity profile] psilogic.livejournal.com 2011-04-05 12:38 pm (UTC)(link)
возможно... но как упражнение - почему нет

[identity profile] sfy-y.livejournal.com 2011-04-05 12:46 pm (UTC)(link)
// op&OpBefore ==!(op&OpAfter) accepted


(undoCase&(!op&OpAfter))?(uf.read(&hb, sizeof(hb)),*hNew++= hb,++i;) :
uf.seek(sizeof(GHarmonicBase), SEEK_CUR),++hOld)

Усё.

[identity profile] psilogic.livejournal.com 2011-04-05 12:50 pm (UTC)(link)
Ничего не понял...
Одно ясно, что это неверно, т.к. в некоторых случаях может понадобится seek+read или read+seek, а у вас - только read либо только seek

[identity profile] sfy-y.livejournal.com 2011-04-05 12:54 pm (UTC)(link)
А совсем тупо - просто макрики или инлайны:

inline seek(){...}
inline read(){...}

[identity profile] sfy-y.livejournal.com 2011-04-05 12:56 pm (UTC)(link)
Там в начале дисклеймер, (предполагается, что программер умеет именовать переменные)

[identity profile] psilogic.livejournal.com 2011-04-05 12:59 pm (UTC)(link)
хрен поймешь этот дисклеймер

но OpBefore == 1, OpAfter == 2, а op == некая комбинация битов, включая OpBefore и OpAfter

[identity profile] sfy-y.livejournal.com 2011-04-05 01:05 pm (UTC)(link)
Тогда делать макрики и не париться.

Но одновременно before и after - не по моим мозгам. :)))


Скачайте как-нить сафроутер (ну, оттуда, например,http://as.fatal.ru/projects/route/index.htm ) - так программил я.

[identity profile] psilogic.livejournal.com 2011-04-05 01:07 pm (UTC)(link)
Это код из обработки undo/redo. В случае операции
1) удаления надо сохранить то, что было ДО удаления (для undo),
2) вставки надо сохранить то, что будет ПОСЛЕ вставки (для redo),
3) изменения надо сохранить то, что было ДО (для undo) и будет ПОСЛЕ (для redo) изменения
так и получается одновременно :)

Page 1 of 3