LINUX.ORG.RU

[c++] Оптимизация кода работы с байтами


0

2

Что-то уже совсем голова не варит. Помогите, пожалуйста, с оптимизацией следующего кода:

void EnableBillTypes(std::list<unsigned int> billTypes)
{
    unsigned char cmd[7] = {CMD_ENABLEBILLTYPES, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    std::list<unsigned int>::iterator it;

    for ( it=billTypes.begin() ; it != billTypes.end(); it++ )
    {
        unsigned char tmp[1] = {0x00};
        switch(*it)
        {
        case 23:
        case 15:
        case 7:
            tmp[0] = 0x80;
            break;
        case 22:
        case 14:
        case 6:
            tmp[0]  = 0x40;
            break;
        case 21:
        case 13:
        case 5:
            tmp[0]  = 0x20;
            break;
        case 20:
        case 12:
        case 4:
            tmp[0]  = 0x10;
            break;
        case 19:
        case 11:
        case 3:
            tmp[0]  = 0x08;
            break;
        case 18:
        case 10:
        case 2:
            tmp[0]  = 0x04;
            break;
        case 17:
        case 9:
        case 1:
            tmp[0]  = 0x02;
            break;
        case 16:
        case 8:
        case 0:
            tmp[0]  = 0x01;
            break;
        }
        if(*it >= 0 && *it <= 7)
        {
            cmd[3] = cmd[3] + tmp[0];
        }
        else if(*it > 7 && *it <= 15)
        {
            cmd[2] = cmd[2] + tmp[0];
        }
        else if(*it > 15 && *it <= 23)
        {
            cmd[1] = cmd[1] + tmp[0];
        }
        else
        {
            printf("Unknown bill type");
            return;
        }
    }
    printf("Send command ENABLE BILL TYPES\n");
    Request(cmd, sizeof(cmd));
}
★★

Про enum'ы ты не слышал?
В чем смысл делать tmp массивом?

Request(cmd, sizeof(cmd));

А не судьба определить cmd отдельным типом?

anonymous ()

> void EnableBillTypes(std::list<unsigned int> billTypes)

передавай по ссылке параметр

aho ()
Ответ на: комментарий от note173

> Нужно оптимизировать размер кода или скорость?

Размер. А вообще «корявость» кода.

SaBo ★★ ()

От switch'а можно избавиться:

    unsigned char tmp = {0x01, 0x02, ...};
    for ( it=billTypes.begin() ; it != billTypes.end(); it++ )
    {
        unsigned int mod = *it % 8;
        if(*it <= 7)
        {
            cmd[3] = cmd[3] + tmp[mod];
        }
        else if(*it <= 15)
        {
            cmd[2] = cmd[2] + tmp[mod + 8];
        }
        else if(*it <= 23)
        {
            cmd[1] = cmd[1] + tmp[mod + 16];
        }
        else
        {
            printf("Unknown bill type");
            return;
        }
    }

anonymous ()
Ответ на: комментарий от anonymous

> Забанятор чешется?

Пепел Розенталя стучит в мое сердце.

Но ведь ты не узнаешь, что это я =P

Рано или поздно ты проговоришься %)

tailgunner ★★★★★ ()
Ответ на: комментарий от anonymous

Я бы даже сказал, что массив тут лишний:

    for ( it=billTypes.begin() ; it != billTypes.end(); it++ )
    {
        unsigned char tmp  = 1 << (*it & 7);
        if(*it <= 7)
        {
            cmd[3] = cmd[3] + tmp;
        }
        else if(*it <= 15)
        {
            cmd[2] = cmd[2] + tmp;
        }
        else if(*it <= 23)
        {
            cmd[1] = cmd[1] + tmp;
        }
        else
        {
            printf("Unknown bill type");
            return;
        }
    }

cdslow ()
Ответ на: комментарий от cdslow

Не могу в битолюбство, но согласен.

anonymous ()
Ответ на: комментарий от cdslow

Можно еще компактнее:

    for ( it=billTypes.begin() ; it != billTypes.end(); it++ )
    {
        unsigned char tmp  = 1 << (*it & 7);
        if (it > 23)
        {
            printf ("Unknown bill type");
            return;
        }
        *it <= 7 ? (cmd[3] += tmp) : (*it <= 15 ? cmd[2] += tmp : cmd[1] += tmp);
    }

note173 ★★★★★ ()
Ответ на: комментарий от tailgunner

Заходи в l-t, заходи в l-t, сука.

class BinaryExpr : public Expr {
public:
	enum Op {
		Add,
		Sub,
		Mul,
		Div,
		Mod,
		Shl,
		Shr,
		Lt,   // <-- сюда заходи, сюда сука
		Gt,
		Le,
		Ge,
		Equal,
		NotEqual,
		BitAnd,
		BitXor,
		BitOr,
		LogicalAnd,
		LogicalOr,
		Comma,
	};

	BinaryExpr(Op o, Expr *a, Expr *b, SourcePos p);
    
	llvm::Value *GetValue(FunctionEmitContext *ctx) const;
        const Type *GetType() const;
        void Print() const;
	
        Expr *Optimize();
        Expr *TypeCheck();
        int EstimateCost() const;

        const Op op;
        Expr *arg0, *arg1;
};
shty ★★★★★ ()
Ответ на: комментарий от aho

На некорректных входных данных лучше падать, чем выдавать некорректный результат.

А ещё лучше их всё-таки сначала проверить :)

cdslow ()
Ответ на: комментарий от cdslow

> На некорректных входных данных лучше падать, чем выдавать некорректный результат.

вот только запись данных по левому адресу - не самый лучший вариант падения

А ещё лучше их всё-таки сначала проверить :)


обязательно надо

aho ()
Ответ на: комментарий от cdslow

а еще можно range-based for-loop сделать :3

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.