символ [] для преобразовывания строкового осуществления в шестнадцатеричную систему

Некоторые параметры, которые у вас есть для анимации графиков в Jupyter / IPython, с использованием matplotlib:

  • Использование display в цикле Используйте IPython.display.display(fig) для отображения фигуры на выходе. Используя цикл, вы хотите очистить вывод до отображения новой фигуры. Обратите внимание, что эта методика дает в целом не столь гладкие результы. Поэтому я бы посоветовал использовать любое из приведенных ниже.
    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    from IPython.display import display, clear_output
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    for i in range(len(x)):
        animate(i)
        clear_output(wait=True)
        display(fig)
        
    plt.show()
  • %matplotlib notebook Использовать магию IPython %matplotlib notebook для установки бэкэнд на бэкэнд ноутбука. Это приведет к сохранению фигуры вместо отображения статического файла png и, следовательно, может также отображать анимацию. Полный пример:
    %matplotlib notebook
    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    
    plt.show()
  • %matplotlib tk Используйте магию IPython %matplotlib tk, чтобы установить бэкэнд на бэкэнд tk. Это откроет фигуру в новом окне графика, который является интерактивным и может также показывать анимацию. Полный пример:
    %matplotlib tk
    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    
    plt.show()
  • Преобразование анимации в видео mp4 (опция, упомянутая уже с помощью @Perfi):
    from IPython.display import HTML
    HTML(ani.to_html5_video())
    
    или использовать plt.rcParams["animation.html"] = "html5" в начале ноутбука. Это потребует наличия видеокодеков ffmpeg для конвертирования в видео HTML5. Затем видео отображается в строке. Поэтому он совместим с бэкэндом %matplotlib inline. Полный пример:
    %matplotlib inline
    import matplotlib.pyplot as plt
    plt.rcParams["animation.html"] = "html5"
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    ani
    %matplotlib inline
    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    
    from IPython.display import HTML
    HTML(ani.to_html5_video())
  • Преобразование анимации в JavaScript:
    from IPython.display import HTML
    HTML(ani.to_jshtml())
    
    или использование plt.rcParams["animation.html"] = "jshtml" в начале ноутбука. Это отобразит анимацию как HTML с JavaScript. Это очень совместимо с большинством новых браузеров, а также с бэкэндом %matplotlib inline. Он доступен в matplotlib 2.1 или выше. Полный пример:
    %matplotlib inline
    import matplotlib.pyplot as plt
    plt.rcParams["animation.html"] = "jshtml"
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    ani
    %matplotlib inline
    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    
    from IPython.display import HTML
    HTML(ani.to_jshtml())
6
задан 8 revs 23 May 2017 в 12:00
поделиться

14 ответов

За счет большей памяти можно составить полную таблицу с 256 записями шестнадцатеричных кодов:

static const char _hex2asciiU_value[256][2] =
    { {'0','0'}, {'0','1'}, /* ..., */ {'F','E'},{'F','F'} };

Затем прямой индекс в таблицу, никакой бит, играющий требуемый.

const char *pHexVal = pHex[*pChar];
pszHex[0] = pHexVal[0];
pszHex[1] = pHexVal[1];
4
ответ дан 8 December 2019 в 03:29
поделиться

Функция, поскольку показано, когда я пишу это, производит неправильный вывод, даже когда _hex2asciiU_value полностью указан. Следующие работы кода, и на моем MacBook Pro на 2.33 ГГц работают приблизительно через 1,9 секунды за 200 000 000 миллионами символов.

#include <iostream>

using namespace std;

static const size_t _h2alen = 256;
static char _hex2asciiU_value[_h2alen][3];

string char_to_hex( const unsigned char* _pArray, unsigned int _len )
{
    string str;
    str.resize(_len*2);
    char* pszHex = &str[0];
    const unsigned char* pEnd = _pArray + _len;
    const char* pHex = _hex2asciiU_value[0];
    for( const unsigned char* pChar = _pArray; pChar != pEnd; pChar++, pszHex += 2 ) {
       pszHex[0] = _hex2asciiU_value[*pChar][0];
       pszHex[1] = _hex2asciiU_value[*pChar][1];
    }
    return str;
}


int main() {
  for(int i=0; i<_h2alen; i++) {
    snprintf(_hex2asciiU_value[i], 3,"%02X", i);
  }
  size_t len = 200000000;
  char* a = new char[len];
  string t1;
  string t2;
  clock_t start;
  srand(time(NULL));
  for(int i=0; i<len; i++) a[i] = rand()&0xFF;
  start = clock();
  t1=char_to_hex((const unsigned char*)a, len);
  cout << "char_to_hex conversion took ---> " << (clock() - start)/(double)CLOCKS_PER_SEC << " seconds\n";
}
0
ответ дан 8 December 2019 в 03:29
поделиться

Последовательно добираясь ~4ms на моем Athlon 64 4200 + (~7ms с исходным кодом)

for( const unsigned char* pChar = _pArray; pChar != pEnd; pChar++) {
    const char* pchars = _hex2asciiU_value[*pChar];
    *pszHex++ = *pchars++;
    *pszHex++ = *pchars;
}
0
ответ дан 8 December 2019 в 03:29
поделиться

Я не уверен выполнение его, больше байтов за один раз будет лучше..., что Вы, вероятно, просто получите тонны неудачных обращений в кэш и значительно замедлите его.

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

0
ответ дан 8 December 2019 в 03:29
поделиться

Удостоверьтесь, что Ваша компиляторная оптимизация включена к самому высокому рабочему уровню.

Вы знаете, флаги как '-O1' к '-03' в gcc.

0
ответ дан 8 December 2019 в 03:29
поделиться

Я нашел, что использование индекса в массив, а не указателя, может ускорить вещи галочка. Все это зависит от того, как Ваш компилятор принимает решение оптимизировать. Ключ - то, что процессор имеет инструкции сделать сложные вещи как [i*2+1] в единственной инструкции.

0
ответ дан 8 December 2019 в 03:29
поделиться

Если Вы довольно одержимы скоростью здесь, можно сделать следующее:

Каждый символ составляет один байт, представляя два шестнадцатеричных значения. Таким образом каждый символ является действительно двумя четырехразрядными значениями.

Так, можно сделать следующее:

  1. Распакуйте четырехразрядные значения к 8-разрядным значениям с помощью умножения или подобной инструкции.
  2. Используйте pshufb, инструкция SSSE3 (Core2-только хотя). Это берет массив 16 8-разрядных входных значений и переставляет их на основе 16 8-разрядных индексов во втором векторе. Так как у Вас есть только 16 возможных символов, это соответствует отлично; входной массив является вектором 0 через символы F, и индексный массив является Вашим распакованным массивом 4-разрядных значений.

Таким образом, в единственной инструкции, Вы выполните 16 поиска по таблице в меньшем количестве часов, чем она обычно берет, чтобы сделать всего одну (pshufb, 1 задержка часов на Penryn).

Так, на вычислительных шагах:

  1. B C D E F G H I J K L M N O P (64-разрядный вектор входных значений, "Векторизовали")-> 0A 0B 0C 0D 0E 0F 0G 0H 0I 0J 0K 0L 0M 0N 0O 0P (128-разрядный вектор индексов, "Вектор B"). Самый легкий путь равняется, вероятно, двум 64-разрядным, умножается.
  2. pshub [0123456789ABCDEF], Вектор B
0
ответ дан 8 December 2019 в 03:29
поделиться

Воздействуйте на 32 бита за один раз (4 символа), затем имейте дело с хвостом в случае необходимости. То, когда я сделал это осуществление с URL, кодирующим полный поиск по таблице для каждого символа, было немного быстрее, чем логические конструкции, таким образом, можно хотеть протестировать это в контексте также для принятия кэширующихся проблем.

3
ответ дан 8 December 2019 в 03:29
поделиться

не собираясь иметь большое значение... *pChar-(ofs*16) может быть, покончили [*pCHar и 0x0F]

1
ответ дан 8 December 2019 в 03:29
поделиться

Для одного, вместо того, чтобы умножиться 16 сделайте a bitshift << 4

Также не используйте std::string, вместо этого просто создайте буфер на "куче" и затем delete это. Это будет более эффективно, чем объектное разрушение, которое необходимо от строки.

2
ответ дан 8 December 2019 в 03:29
поделиться

Изменение

    ofs = *pChar >> 4;
    pszHex[0] = pHex[ofs];
    pszHex[1] = pHex[*pChar-(ofs*16)];

кому:

    int upper = *pChar >> 4;
    int lower = *pChar & 0x0f;
    pszHex[0] = pHex[upper];
    pszHex[1] = pHex[lower];

результаты примерно в 5%-м ускорении.

Запись результата двух байтов во время, как предложено Robert приводит приблизительно к 18%-му ускорению. Код изменяется на:

_result.resize(_len*2);
short* pszHex = (short*) &_result[0];
const unsigned char* pEnd = _pArray + _len;

const char* pHex = _hex2asciiU_value;
for(const unsigned char* pChar = _pArray;
    pChar != pEnd;
    pChar++, ++pszHex )
{
    *pszHex = bytes_to_chars[*pChar];
}

Необходимая инициализация:

short short_table[256];

for (int i = 0; i < 256; ++i)
{
    char* pc = (char*) &short_table[i];
    pc[0] = _hex2asciiU_value[i >> 4];
    pc[1] = _hex2asciiU_value[i & 0x0f];
}

Выполнение его, 2 байта за один раз или 4 байта за один раз, вероятно, приведут к еще большим ускорениям, как указано Allan Wind, но затем это становится более хитрым, когда необходимо иметь дело с нечетными символами.

Если Вы чувствуете себя предприимчивыми, Вы могли бы попытаться адаптировать устройство Вареного пудинга, чтобы сделать это.

Результаты находятся на процессоре Intel Core Duo 2 и gcc -O3.

Всегда мера, что Вы на самом деле получаете более быстрые результаты — pessimization, симулирующий быть оптимизацией, менее, чем бесполезна.

Всегда тест, что Вы получаете корректные результаты — ошибка, симулирующая быть оптимизацией, совершенно опасен.

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

(Обязательная ссылка на кодирование для жестокого психопата, который знает, где Вы живете.)

1
ответ дан 8 December 2019 в 03:29
поделиться

Быстрее C Implmentation

Это работает почти 3x быстрее, чем реализация C++. Не уверенный, почему, поскольку это довольно подобно. Для последней реализации C++, что я отправил его, занял 6,8 секунд для пробежки 200 000 000 символьных массивов. Реализация заняла только 2,2 секунды.

#include <stdio.h>
#include <stdlib.h>

char* char_to_hex(const unsigned char* p_array, 
                  unsigned int p_array_len,
                  char** hex2ascii)
{
    unsigned char* str = malloc(p_array_len*2+1);
    const unsigned char* p_end = p_array + p_array_len;
    size_t pos=0;
    const unsigned char* p;
    for( p = p_array; p != p_end; p++, pos+=2 ) {
       str[pos] = hex2ascii[*p][0];
       str[pos+1] = hex2ascii[*p][1];
    }
    return (char*)str;
}

int main()
{
  size_t hex2ascii_len = 256;
  char** hex2ascii;
  int i;
  hex2ascii = malloc(hex2ascii_len*sizeof(char*));
  for(i=0; i<hex2ascii_len; i++) {
    hex2ascii[i] = malloc(3*sizeof(char));    
    snprintf(hex2ascii[i], 3,"%02X", i);
  }
  size_t len = 8;
  const unsigned char a[] = "DO NOT WANT";
  printf("%s\n", char_to_hex((const unsigned char*)a, len, (char**)hex2ascii));
}

enter image description here

4
ответ дан 8 December 2019 в 03:29
поделиться

Эта функция блока (базирующийся от моего предыдущего сообщения здесь, но я должен был изменить понятие немного для получения, это для фактической работы) обрабатывает 3,3 миллиарда вводимых символов в секунду (6,6 миллиардов выходных символов) на одном ядре Core 2 Конроу 3 ГГц. Penryn, вероятно, быстрее.

%include "x86inc.asm"

SECTION_RODATA
pb_f0: times 16 db 0xf0
pb_0f: times 16 db 0x0f
pb_hex: db 48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70

SECTION .text

; int convert_string_to_hex( char *input, char *output, int len )

cglobal _convert_string_to_hex,3,3
    movdqa xmm6, [pb_f0 GLOBAL]
    movdqa xmm7, [pb_0f GLOBAL]
.loop:
    movdqa xmm5, [pb_hex GLOBAL]
    movdqa xmm4, [pb_hex GLOBAL]
    movq   xmm0, [r0+r2-8]
    movq   xmm2, [r0+r2-16]
    movq   xmm1, xmm0
    movq   xmm3, xmm2
    pand   xmm0, xmm6 ;high bits
    pand   xmm2, xmm6
    psrlq  xmm0, 4
    psrlq  xmm2, 4
    pand   xmm1, xmm7 ;low bits
    pand   xmm3, xmm7
    punpcklbw xmm0, xmm1
    punpcklbw xmm2, xmm3
    pshufb xmm4, xmm0
    pshufb xmm5, xmm2
    movdqa [r1+r2*2-16], xmm4
    movdqa [r1+r2*2-32], xmm5
    sub r2, 16
    jg .loop
    REP_RET

Обратите внимание, что это использует x264 синтаксис блока, который делает это более портативным (к 32-разрядному по сравнению с 64-разрядным, и т.д.). Преобразовать это в синтаксис по Вашему выбору тривиально: r0, r1, r2 являются этими тремя аргументами функциям в регистрах. Это немного похоже на псевдокод. Или можно просто получить common/x86/x86inc.asm от x264 дерева и включать это для выполнения его исходно.

P.S. Переполнение стека, я неправильно для того, чтобы напрасно тратить время на такой тривиальной вещи? Или действительно ли это является потрясающим?

9
ответ дан 8 December 2019 в 03:29
поделиться

Это - моя версия, которая, в отличие от версии OP, не принимает это std::basic_string имеет его данные в непрерывном регионе:

#include <string>

using std::string;

static char const* digits("0123456789ABCDEF");

string
tohex(string const& data)
{
    string result(data.size() * 2, 0);
    string::iterator ptr(result.begin());
    for (string::const_iterator cur(data.begin()), end(data.end()); cur != end; ++cur) {
        unsigned char c(*cur);
        *ptr++ = digits[c >> 4];
        *ptr++ = digits[c & 15];
    }
    return result;
}
1
ответ дан 8 December 2019 в 03:29
поделиться
Другие вопросы по тегам:

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