Как делегировать управление из строки в ряд функций в C - PullRequest
0 голосов
/ 26 марта 2011

Это критическая для моего приложения часть производительности, и я использую NDK (c) для обработки большого массива растровых изображений.

int blender(const char* blendMode, int c1, int c2, int amount){

    int sob, sog, sor, soa, dsr, dsg, dsb, dsa = 0;

    dsr = Argb_GetRed(c1);
    dsg = Argb_GetGreen(c1);
    dsb = Argb_GetBlue(c1);
    dsa = Argb_GetAlpha(c1);

    sor = Argb_GetRed(c2);
    sog = Argb_GetGreen(c2);
    sob = Argb_GetBlue(c2);
    soa = Argb_GetAlpha(c2);


    int src_alpha, mix_alpha, dst_alpha;

    src_alpha = soa * ((255 * amount) / 100) >> 8;

    if (!strcmp(blendMode, "normal")) {
            PSD_BLEND_NORMAL(dsr, sor, mix_alpha);
            PSD_BLEND_NORMAL(dsg, sog, mix_alpha);
            PSD_BLEND_NORMAL(dsb, sob, mix_alpha);
    }
    else if (!strcmp(blendMode, "exclusion")) {

            mix_alpha = soa / 255;
            //.... it's not always just the 3 macros

            PSD_BLEND_EXCLUSION(dsr, sor, mix_alpha);
            PSD_BLEND_EXCLUSION(dsg, sog, mix_alpha);
            PSD_BLEND_EXCLUSION(dsb, sob, mix_alpha);
    }

    ~~~~~~~~~ X 20 or so blend modes ~~~~~~~~~~~~
}

В настоящее время он выполняет эту функцию блендера на каждом пикселе и выполняет переключение (явно неэффективное)

также, она должна принимать исходную команду как строку (из json и передаваться через java)

Я могу придумать пару способов сделать его более эффективным, но все они включают в себя написание двух гигантских операторов переключения. Я бы предпочел использовать 1 оператор switch или поиск, если это возможно

Спасибо!

1 Ответ

1 голос
/ 26 марта 2011

Довольно неприятная проблема, но у меня возникла "хакерская" идея.

Если имена ' blendMode ' выбраны правильно, вы можете сравнить только первые два (или три ) буквы строк.Если есть несколько строк с одинаковыми первыми буквами, вы можете создать специальный случай и сравнить первую и третью буквы и т. Д.

Этот трюк сделает код намного быстрее, чем постоянно вызывает strcmp ().Также может помочь включение функции сравнения.

Вот некоторый код:

/* compares first two letters of the string */
inline int fast_cmp(const char *mode, const char *cmp) {
    return (mode[0] == cmp[0] && mode[1] == cmp[1]) ? 1 : 0;
}

if( fast_cmp(blendMode, "no") ); /* for "normal"    */
if( fast_cmp(blendMode, "ex") ); /* for "exclusion" */

В действии: http://ideone.com/OiXS0

Конечно, сравнения можно записать непосредственно, если/ else заявления, но это может сбить с толку.Это можно исправить с помощью маленького и изящного макроса:

#define FAST_CMP(x, y) x[0] == y[0] && x[1] == y[1]

А вот макрос в действии: http://ideone.com/NQFwW

Эта версия макроса, пожалуй, самый быстрый способ сделать сравнение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...