Оптимизация алгоритма поиска в C

Вы можете использовать конструктор DataFrame с lists, созданный путем преобразования в numpy array с помощью values с tolist :

import pandas as pd

d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
                ['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
print (df2)
       teams
0  [SF, NYG]
1  [SF, NYG]
2  [SF, NYG]
3  [SF, NYG]
4  [SF, NYG]
5  [SF, NYG]
6  [SF, NYG]

df2[['team1','team2']] = pd.DataFrame(df2.teams.values.tolist(), index= df2.index)
print (df2)
       teams team1 team2
0  [SF, NYG]    SF   NYG
1  [SF, NYG]    SF   NYG
2  [SF, NYG]    SF   NYG
3  [SF, NYG]    SF   NYG
4  [SF, NYG]    SF   NYG
5  [SF, NYG]    SF   NYG
6  [SF, NYG]    SF   NYG

И для нового DataFrame:

df3 = pd.DataFrame(df2['teams'].values.tolist(), columns=['team1','team2'])
print (df3)
  team1 team2
0    SF   NYG
1    SF   NYG
2    SF   NYG
3    SF   NYG
4    SF   NYG
5    SF   NYG
6    SF   NYG

Решение с apply(pd.Series) очень медленно:

#7k rows
df2 = pd.concat([df2]*1000).reset_index(drop=True)

In [89]: %timeit df2['teams'].apply(pd.Series)
1 loop, best of 3: 1.15 s per loop

In [90]: %timeit pd.DataFrame(df2['teams'].values.tolist(), columns=['team1','team2'])
1000 loops, best of 3: 820 µs per loop

9
задан Martin 19 August 2008 в 09:57
поделиться

9 ответов

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

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

24
ответ дан 4 December 2019 в 07:49
поделиться

Я думаю, это не будет иметь большую часть значения. Компилятор уже оптимизирует его в том направлении.

Кроме того, переменная, я не оказываю большое влияние, слово, остается постоянной всюду по функции, и остальное является слишком большим для помещений в любой регистр. Это - только вопрос, насколько большой кэш и если целый массив мог бы соответствовать там.

Сравнения строк являются довольно дорогими в вычислительном отношении.

Можно ли, возможно, использовать некоторое хеширование для массива перед поиском?

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

Существует известная техника как метод сигнальной метки. Для использования метода сигнальной метки необходимо знать о длине "массива []". Можно удалить "массив [я]! = ПУСТОЕ" сравнение при помощи сигнальной метки.

int lookup(char *word, char*array[], int array_len)
{
    int i = 0;
    array[array_len] = word;
    for (;; ++i)
        if (strcmp(word, array[i]) == 0) 
            break;
    array[array_len] = NULL;
    return (i != array_len) ? i : -1;
}
2
ответ дан 4 December 2019 в 07:49
поделиться

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

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

Мои 2 пункта (C-psuedocode):

wrd_end = wrd_ptr + wrd_len;
arr_end = arr_ptr - wrd_len;
while (arr_ptr < arr_end)
{
    wrd_beg = wrd_ptr; arr_beg = arr_ptr;
    while (wrd_ptr == arr_ptr)
    {
        wrd_ptr++; arr_ptr++;
        if (wrd_ptr == wrd_en)
            return wrd_beg;
    }
    wrd_ptr++;
}
0
ответ дан 4 December 2019 в 07:49
поделиться

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

Но можно сделать вещи немного быстрее путем замены вещей как

for (i = 0; i < n; ++i)
    foo(a[i]);

с

char **p = a;
for (i = 0; i < n; ++i)
    foo(*p);
    ++p;

Если существует известное значение в конце массива (например, Пустой УКАЗАТЕЛЬ), можно устранить счетчик цикла:

for (p = a; *p != NULL; ++p)
    foo(*p)

Удача, это - замечательная книга!

1
ответ дан 4 December 2019 в 07:49
поделиться

Mark Harrison: Ваш для цикла никогда не будет завершаться! (++ p располагается с отступом, но не на самом деле в для :-)

Кроме того, переключение между указателями и индексацией не будет обычно иметь никакого эффекта на производительность, и при этом добавление не зарегистрирует ключевые слова (как циновка уже упоминает) - компилятор достаточно умен для применения этих преобразований в соответствующих случаях, и если Вы скажете это достаточно о Вашей дуге CPU, то это сделает лучшее задание их, чем руководство psuedo-micro-optimizations.

0
ответ дан 4 December 2019 в 07:49
поделиться

Более быстрый путь к строкам совпадения состоял бы в том, чтобы сохранить их стиль Паскаля. Если Вам не нужны больше чем 255 символов на строку, сохраните их примерно как это с количеством в первом байте:

char s[] = "\x05Hello";

Затем можно сделать:

for(i=0; i<len; ++i) {
    s_len = strings[i][0];
    if(
        s_len == match_len
        && strings[i][s_len] == match[s_len-1]
        && 0 == memcmp(strings[i]+1, match, s_len-1)
    ) {
        return 1;
    }
}

И получить действительно быстрые подсказки упреждающей выборки дополнительной памяти для строки запускаются + 64, + 128 и запуск следующей строки. Но это является просто сумасшедшим.:-)

0
ответ дан 4 December 2019 в 07:49
поделиться

Другой быстрый способ сделать это состоит в том, чтобы добраться, Ваш компилятор для использования SSE2 оптимизировал memcmp. Используйте массивы символов фиксированной длины и выровняйтесь так, строка запускается на 64-байтовом выравнивании. Затем я полагаю, что можно получить хорошие функции memcmp при передаче соответствия символа константы [64] вместо символа константы *соответствие в функцию или соответствие strncpy в 64,128,256, безотносительно массива байтов.

Думая немного больше об этом, эти функции соответствия SSE2 могли бы быть частью пакетов как библиотеки акселератора Intel и AMD. Проверьте их.

0
ответ дан 4 December 2019 в 07:49
поделиться

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

Если Вы готовы провести некоторое время, заранее предварительно обрабатывающее ссылочный массив, необходимо погуглить "Самую Быструю Программу скрэббла В мире" и реализацию это. Спойлер: это - DAG, оптимизированный для символьных поисков.

0
ответ дан 4 December 2019 в 07:49
поделиться
Другие вопросы по тегам:

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