Обработка строк в Cython

Я занимался этой проблемой в течение нескольких дней, несмотря на поиск решения в сети. Сначала я переместил свой проект в Netbeans, и все работало нормально. Затем я вернулся к eclipse-> properties-> java compile-> Building и изменил опцию «Несопоставимый путь сборки» с ошибки на предупреждение, а затем произвел обновление maven, и это сработало.

28
задан itsadok 3 June 2009 в 10:46
поделиться

4 ответа

Я проголосовал за ответ «профилируйте его», но хотел добавить следующее: там, где это возможно, лучшая оптимизация, которую вы можете сделать, - это использовать стандартные библиотеки Python или встроенные функции для выполнения ваших задач. хотеть. Обычно они реализуются на C и обеспечивают производительность, в целом эквивалентную любому расширению, включая расширения, написанные на Cython. Если ваши алгоритмы выполняют символьные циклы в Python, то это должно быть первым делом, если это возможно.

Но если у вас есть алгоритмы, которые нельзя переработать с точки зрения встроенных модулей или других существующих стандартных библиотек, Cython кажется разумным подходом. Он просто компилирует псевдо-Python до нативного кода и на самом деле так же подходит для строковых операций, как и любая другая операция. Но я' Я не уверен, что вы увидите большую выгоду от использования Cython, если просто передадите ему идиоматический код Python. Максимальное преимущество будет, если вы сможете переписать некоторые или все алгоритмы на C, чтобы низкоуровневые операции не переводили переменные постоянно через барьер Python / C.

Наконец, Unicode - вы подразумевали, что это может быть «большой проблемой», но не указано, как вы ее используете. Cython предположительно создаст код C, который вызывает соответствующие API-интерфейсы Python, которые обрабатывают Unicode, поэтому функциональные возможности вряд ли будут ограничены. Однако обработка строк Unicode в C нетривиальна и может означать, что идея переписать некоторые из ваших алгоритмов на C для повышения производительности не стоит усилий. Многие классические строковые алгоритмы просто не работают со многими кодировками Unicode, которые не являются «строками».

11
ответ дан 28 November 2019 в 03:28
поделиться

Это очень интересный вопрос. Cython по своей сути - это инструмент для интеграции python с типами данных C. Он не предоставляет никаких функций, помогающих работать со строками, вероятно, потому, что на них не так много спроса, как на конкретные функции Numpy.

Сказав это, вы вполне можете использовать Cython для взаимодействия с существующим C / Библиотеки C ++, предназначенные для решения описываемых вами типов проблем. Для обработки HTML / XML вы можете, например, изучить libxml . Однако есть (конечно) готовые привязки python , уже доступные именно для этого. Я широко использовал lxml для обработки HTML, и он делает все, что мне нужно, и делает это быстро , плюс он довольно хорошо обрабатывает Unicode.

В вашем случае, я думаю, лучше всего подойдет комбинация lxml и пользовательских функций C. Например, вы можете «легко» создать быструю функцию для поиска самых длинных подстрок в C, так как это можно сделать на уровне байтов (напомним, что строка в C - это просто char *, который представляет собой массив байтов). Затем вы могли бы сопоставить их с python (который Cython упростит для вас) и продолжить в абстрагированных небесах юникода :). Конечно, нетривиально, но может стоить усилий, если от этого зависит производительность вашего приложения.

Кроме того, есть, конечно, хорошие (хотя и нетривиальные) подходы к работе с Unicode в C / C ++. Эта статья Эвана Джонса может помочь вам решить, стоит ли затраченных усилий.

сделать быструю функцию для поиска самых длинных подстрок в C, так как это может быть сделано на уровне байтов (напомним, что строка в C - это просто char *, который представляет собой массив байтов). Затем вы могли бы сопоставить их с python (который Cython упростит для вас) и продолжить в абстрагированных небесах юникода :). Конечно, нетривиально, но может стоить усилий, если от этого зависит производительность вашего приложения.

Кроме того, есть, конечно, хорошие (хотя и нетривиальные) подходы к работе с Unicode в C / C ++. Эта статья Эвана Джонса может помочь вам решить, стоит ли затраченных усилий.

сделать быструю функцию для поиска самых длинных подстрок в C, так как это может быть сделано на уровне байтов (напомним, что строка в C - это просто char *, который представляет собой массив байтов). Затем вы могли бы сопоставить их с python (который Cython упростит для вас) и продолжить в абстрагированных небесах юникода :). Конечно, нетривиально, но может стоить усилий, если от этого зависит производительность вашего приложения.

Кроме того, есть, конечно, хорошие (хотя и нетривиальные) подходы к работе с Unicode в C / C ++. Эта статья Эвана Джонса может помочь вам решить, стоит ли затраченных усилий.

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

Есть, конечно, хорошие (хотя и нетривиальные) подходы к работе с юникодом в C / C ++. Эта статья Эвана Джонса может помочь вам решить, стоит ли затраченных усилий.

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

Есть, конечно, хорошие (хотя и нетривиальные) подходы к работе с юникодом в C / C ++. Эта статья Эвана Джонса может помочь вам решить, стоит ли затраченных усилий.

5
ответ дан 28 November 2019 в 03:28
поделиться

Для полноты картины я просто написал (часть) кода обработки строк на C.

Как оказалось, это до смешного просто чтобы начать писать расширения c для python. Строки Unicode - это просто массивы Py_UNICODE, которые могут быть int или short, в зависимости от сборки python.

Я получил улучшение x20, преобразовав код вроде

s = re.sub(r' +', ' ', s)

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

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

9
ответ дан 28 November 2019 в 03:28
поделиться

«До смешного легко» - термин очень относительный. «Начало работы» - это просто так. Написание надежных расширений на C требует очень внимательного отношения к таким вещам, как подсчет ссылок, выделение / освобождение памяти и обработка ошибок. Cython делает большую часть этого за вас.

Строка, отличная от Unicode, в Cython является либо объектом Python str, либо массивом символов, как в C. Какая документация по Cython, по вашему мнению, вам нужна?

Я рекомендую вам попробовать Cython самостоятельно. НО, прежде чем вы это сделаете, я настоятельно рекомендую вам проверить свой код Python на предмет неэффективности. Иногда можно до смешного легко получить большое ускорение.

Например, сжатие пробелов ... с использованием

re.sub(' +', ' ', s) # one space in pattern

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

re.sub('  +', ' ', s) # two spaces in pattern

дает точно такие же результаты и может работать быстрее ... посмотрим:

Длина всех прогонов 1: Скорость в 3,4 раза выше. Не показано: чем длиннее входная строка, тем лучше.

\python26\python -mtimeit -s"s='now is the winter of our discontent'; import re; x = re.compile(' +').sub" "x(' ', s)"
100000 loops, best of 3: 8.26 usec per loop

\python26\python -mtimeit -s"s='now is the winter of our discontent'; import re; x = re.compile('  +').sub" "x(' ', s)"
100000 loops, best of 3: 2.41 usec per loop

При длине одного прогона 2 коэффициент скорости равен 2,5. При длине всех участков 2 передаточное число равно 1,2. Учитывая все обстоятельства, неплохая окупаемость вложения в одно нажатие клавиши.

re.sub('  +', ' ', s) # two spaces in pattern

дает точно такие же результаты и может работать быстрее ... давайте посмотрим:

Длина всех прогонов 1: Скорость выполнения в 3,4 раза выше. Не показано: чем длиннее входная строка, тем лучше.

\python26\python -mtimeit -s"s='now is the winter of our discontent'; import re; x = re.compile(' +').sub" "x(' ', s)"
100000 loops, best of 3: 8.26 usec per loop

\python26\python -mtimeit -s"s='now is the winter of our discontent'; import re; x = re.compile('  +').sub" "x(' ', s)"
100000 loops, best of 3: 2.41 usec per loop

При длине одного прогона 2 коэффициент скорости равен 2,5. При длине всех участков 2 передаточное число равно 1,2. Учитывая все обстоятельства, неплохая окупаемость вложения в одно нажатие клавиши.

re.sub('  +', ' ', s) # two spaces in pattern

дает точно такие же результаты и может работать быстрее ... давайте посмотрим:

Длина всех прогонов 1: Скорость выполнения в 3,4 раза выше. Не показано: чем длиннее входная строка, тем лучше.

\python26\python -mtimeit -s"s='now is the winter of our discontent'; import re; x = re.compile(' +').sub" "x(' ', s)"
100000 loops, best of 3: 8.26 usec per loop

\python26\python -mtimeit -s"s='now is the winter of our discontent'; import re; x = re.compile('  +').sub" "x(' ', s)"
100000 loops, best of 3: 2.41 usec per loop

При длине одного прогона 2 коэффициент скорости равен 2,5. При длине всех участков 2 передаточное число равно 1,2. Учитывая все обстоятельства, неплохая окупаемость вложения в одно нажатие клавиши.

8
ответ дан 28 November 2019 в 03:28
поделиться
Другие вопросы по тегам:

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