Вопрос о производительности: Самый Быстрый способ преобразовать шестнадцатеричный символ в его числовое значение в Java?

Это ошибка в C-коде. В строке surface.c 2258 для surf_blits имеется следующий тест:

    if (dest->flags & SDL_OPENGL &&
        !(dest->flags & (SDL_OPENGLBLIT & ~SDL_OPENGL))) {
        bliterrornum = BLITS_ERR_NO_OPENGL_SURF;
        goto bliterror;
    }

Тогда как в строке surface.c 2121 для surf_blit код:

#if IS_SDLv1
    if (dest->flags & SDL_OPENGL &&
        !(dest->flags & (SDL_OPENGLBLIT & ~SDL_OPENGL)))
        return RAISE(pgExc_SDLError,
                     "Cannot blit to OPENGL Surfaces (OPENGLBLIT is ok)");
#endif /* IS_SDLv1 */

Обратите внимание на #if IS_SDLv1.

Проблема, кажется, исходит из SDL_OPENGLBLIT, который в настоящее время устарел .

Не используйте устаревший режим SDL_OPENGLBLIT, который разрешал как блиттинг, так и использование OpenGL. Этот флаг устарел, по нескольким причинам. При многочисленных обстоятельствах использование SDL_OPENGLBLIT может повредить ваше состояние OpenGL.

blockquote>

К сожалению, я не эксперт в OpenGL и не могу объяснить дальше. Надеюсь, кто-то может опубликовать более точный ответ.

Что я точно знаю, так это то, что я могу поднять BLITS_ERR_SEQUENCE_SURF непосредственно перед (например, давая pygame.Rect в качестве первого объекта в blit_args), и я не могу поднять BLITS_ERR_INVALID_DESTINATION сразу после. [ 1121]

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

РЕДАКТИРОВАТЬ

Я могу подтвердить, что, если я добавлю #if IS_SDLv1 вокруг теста выше и перекомпилирую Pygame, это сработает. Не знаю почему, хотя! ☺

Я поднял проблему на GitHub .

9
задан Epaga 21 October 2008 в 07:59
поделиться

10 ответов

Предварительно инициализированный массив был бы быстрее, чем HashMap. Что-то вроде этого:

int CharValues['f'-'0'+1] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, ... -1, 10, 11, 12, ...};

if (c < '0' || c > 'f') {
    throw new IllegalArgumentException();
}
int n = CharValues[c-'0'];
if (n < 0) {
    throw new IllegalArgumentException();
}
// n contains the digit value

Необходимо сравнить этого метода с другими методами (такими как прямой метод Jon Skeet) для определения, который будет самым быстрым для приложения.

16
ответ дан 4 December 2019 в 05:58
поделиться

Хеш-таблица была бы относительно медленной. Это довольно быстро:

if (c >= '0' && c <= '9')
{
    return c - '0';
}
if (c >= 'a' && c <= 'f')
{
    return c - 'a' + 10;
}
if (c >= 'A' && c <= 'F')
{
    return c - 'A' + 10;
}
throw new IllegalArgumentException();

Другая опция состояла бы в том, чтобы попробовать переключатель/оператор выбора. Массив мог бы быть хорошо, если это находится в кэше, но мисс могла бы быть дорогой.

14
ответ дан 4 December 2019 в 05:58
поделиться

Я не помню, чтобы видел этот метод раньше, но Микко Рантанен указал на это уравнение в комментарии к вопросу: Код гольфа - двоичное преобразование в шестнадцатеричное (сырое) значение

(char | 32) % 39 - 9

Я не знаю, как оно будет измеряться (возможно, кто-то может добавить его в приведенный выше тест и запустить это, но я предполагаю, что% убивает производительность) - но это аккуратная, простая однострочная для преобразования одного символа в шестнадцатеричное в десятичное. Ручки 0-9, AF, аф.

Я не знаю, как он будет тестироваться (возможно, кто-то может добавить его к тесту выше и запустить его, но я предполагаю, что% убивает производительность) - но это аккуратная, простая однострочная строка для преобразования одного символа в шестнадцатеричное в десятичное. Ручки 0-9, AF, аф.

Я не знаю, как он будет тестироваться (возможно, кто-то может добавить его к тесту выше и запустить его, но я предполагаю, что% убивает производительность) - но это аккуратная, простая однострочная строка для преобразования одного символа в шестнадцатеричное в десятичное. Ручки 0-9, AF, аф.

4
ответ дан 4 December 2019 в 05:58
поделиться
int CharValues[256] = 
{
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,0,1,2,3,4,5,6,7,8,9,16,16,16,16,16,16,16,
16,10,11,12,13,14,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,10,11,12,13,14,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16
}

int n = CharValues[c];

if (n == 16)
 throw new IllegalArgumentException();

// n contains the digit value
4
ответ дан 4 December 2019 в 05:58
поделиться

Character.getNumericValue (символ) иначе:

char c = 'a';
System.out.println(c + "->" + Character.getNumericValue(c));

Печать 'a-> 10' как Вы хочет, например. Кто-то еще должен был бы прокомментировать эффективность статического вызова метода по сравнению с поиском HashMap, или Вы могли проверить ее для себя. Это кажется инструментом для очистки/больше, читаемым мне все же.

2
ответ дан 4 December 2019 в 05:58
поделиться

Используя массив должно быть самым быстрым.

Массив мог иметь размер 16, 16^2, 16^3, 16^4 и т.д.

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

Будет зона наилучшего восприятия, где это наиболее стоит, возможно 4 цифры (64k таблица).

3
ответ дан 4 December 2019 в 05:58
поделиться

простой, но медленный:

int i = Integer.parseInt(String.ValueOf(c), 16);

быстрее:

int i = Character.digit(c, 16);

Я привычка использую любой специальный код для "проблем производительности". Если Вы действительно часто будете использовать это, то JIT создаст скомпилированный код, и выполнение станет быстрым. Содержите свой код в чистоте. Вы можете иметь попытку и записать тест производительности, сравнивающий время выполнения из кода выше и любой специальной реализации - я поставил Вас, привычка получает существенные улучшения.

2
ответ дан 4 December 2019 в 05:58
поделиться

Стоит отметить, что вы выполняете синхронизацию% операции в большинстве ваших тестов. Эта операция занимает примерно столько же времени, что и некоторые другие параметры.

private static byte lookUpTest(int i) {
    return (byte) cs[i%cs.length];
}
2
ответ дан 4 December 2019 в 05:58
поделиться

Я не думаю, что можно победить прямой поиск массива.

static final int[] precalc = new int['f'+1];
static {
    for (char c='0'; c<='9'; c++) precalc[c] = c-'0';
    for (char c='A'; c<='F'; c++) precalc[c] = c-'A';
    for (char c='a'; c<='f'; c++) precalc[c] = c-'a';
}

System.out.println(precalc['f']);
2
ответ дан 4 December 2019 в 05:58
поделиться

Вот моя настроенная версия кода Greg. На моем поле это незначительно быстрее - но вероятно в шуме. Это избегает проверки нижней границы и не должно делать никакого вычитания. Создание массива 64K и предотвращение любой проверки принадлежности к диапазону, казалось, замедлили вещи - но снова, с синхронизацией как это фактически невозможно быть уверенным, что реально и что является шумом.

public class HexParser
{
    private static final byte VALUES = new int['f'];

    // Easier to get right for bozos like me (Jon) than
    // a hard-coded array :)
    static
    {
        for (int i=0; i < VALUES.length; i++)
        {
            VALUES[i] = (byte) -1;
        }
        for (int i='0'; i <= '9'; i++)
        {
            VALUES[i] = (byte) i-'0';
        }
        for (int i='A'; i <= 'F'; i++)
        {
            VALUES[i] = (byte) (i-'A'+10);
        }
        for (int i='a'; i <= 'f'; i++)
        {
            VALUES[i] = (byte) (i-'a'+10);
        }
    }

    public static byte parseHexChar(char c)
    {
        if (c > 'f')
        {
            throw new IllegalArgumentException();
        }
        byte ret = VALUES[c];
        if (ret == -1)
        {
            throw new IllegalArgumentException();
        }
        return ret;
    }
}
2
ответ дан 4 December 2019 в 05:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: