LINUX.ORG.RU
ФорумTalks

С уделал Python по скорости разработки ;)

 , ,


0

2

Короче, мне надо было сделать следующее. Считать из ASCII-файла с вещественными числами ровно N чисел, причём эти числа идут в файле через пробел и иногда происходит перевод строки, типа такого:

1.45E+4 5E+6 7E+8
2.42E+1 7.7E+2 1E-1 5E-6 4E-6
1E-6 1E-8
.....
Этих чисел в файле M, M ~ 1E+7, N ~ 1E+6

Люблю Python, полез в инет выяснять, как это сделать на нём - везде пример с чтением файла построчно и потом разбор строки. Плюнул и написал прогу на C за пару минут

Eddy_Em, твоя взяла - Python отстой, C рулит :)

Если кто знает, как это сделать в Python без чтения построчно - пишите

Update: размер файла - порядка 24Гигов, надо вывести N-ое число (а не все N чисел)

★★★★☆

Последнее исправление: Sahas (всего исправлений: 1)
Ответ на: комментарий от proud_anon

спасибо, это годный вариант =) Правда, скорость работы программы получилась over 5 минут (по сравнению с 1 мин на С)

Sahas ★★★★☆
() автор топика
Ответ на: комментарий от Sahas

24Г

На таком размере нужно после каждых N итераций обрабатывать результаты, и выкидывать их из памяти. А то представь себе что 24Гб чисел у тебя загрузятся в память. И т.к. решение нетривиально, решать в лоб не вариант, то самое простое решение, которое ты ищещь, скорее всего окажется неправильным.

drull ★☆☆☆
()
Ответ на: комментарий от Sahas

Правда, скорость работы программы получилась over 5 минут (по сравнению с 1 мин на С)

Я ожидал, что тормозить будет жёсткий диск, но раз такое дело, можно попробовать PyPy.

proud_anon ★★★★★
()
Ответ на: комментарий от aidan

а как вывести только последнее число? а то из 24гигов делать еще файл на пару гигов не комильфо =)

Sahas ★★★★☆
() автор топика
Ответ на: комментарий от drull

да, я не совсем корректно сформулировал задачу. Надо вывести последнее число только (N-ое)

Sahas ★★★★☆
() автор топика
Ответ на: комментарий от Sahas
awk -vRS=' ' -vFS="\n" '{print $1}' test | head -n5 | tail -n 1

Только вот КМК awk ляжет на таких объемах.

drull ★☆☆☆
()
Последнее исправление: drull (всего исправлений: 1)

То ли я чего-то не понял, то ли тред полон наркоманов - какой еще парсинг?

import sys

N, n = 100500, 0
for l in sys.readlines():
  lst = [float(i) for i in l.split()]
  if n+len(lst) >= N:
    print lst(N-n)
    break
  else:
    n += len(lst)

это если не накапливать список числе в памяти.

tailgunner ★★★★★
()
Ответ на: комментарий от E

время работы большое (>3 минут против 1 мин на С). Видимо, чтение по строкам занимает много времени, поскольку чисел в строке может быть очень много...

Sahas ★★★★☆
() автор топика

Ничего ви не понимаете в методах скоростной обработки

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

tr ' ' '\n' | python yourprog.py
derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 2)
Ответ на: комментарий от tailgunner
for l in sys.readlines():
AttributeError: 'module' object has no attribute 'readlines'

похоже, чтение по строкам будет очень медленное. Не дождался околнчания ни одной проги на python... :(

Sahas ★★★★☆
() автор топика
Ответ на: комментарий от Sahas

С уделал Python по скорости разработки ;)

Я этот скрипт набросал за 10 минут (из них 7 - гугление парсера с итератором). Про время выполнения в ОПе ни слова. Если нужно, можно скомпилировать regexp, так выйдет раза в полтора быстрее. Если нужно ещё быстрее - придётся поступиться скоростью разработки (если тебе действительно именно это было нужно, мой юный зелёный друг) и читать побайтово.

E ★★★
()
Ответ на: комментарий от Sahas

AttributeError: 'module' object has no attribute 'readlines'

sys.stdin, естественно. Это пример, я его не запускал - тестовых данных нету.

похоже, чтение по строкам будет очень медленное

ЕМНИП, там итератор.

tailgunner ★★★★★
()
Ответ на: комментарий от E

скорость работы не очень важна, просто я не ожидал настолько сильного замедления работы для простой программы чтения из файла. Т.е. по идее, чтение посимвольно что в питоне, что в С должно быть примерно с одной скоростью... Или я не прав?

Sahas ★★★★☆
() автор топика
Последнее исправление: Sahas (всего исправлений: 1)
Ответ на: комментарий от Sahas

Подумаешь, вместо 8ГиБ/с после пайпа получаешь 4ГиБ/с. Т.е. твой файл не за 24 секунды проходит, а 48. Ты его обрабатываешь дольше. Зато код самой программы проще, и, следовательно, быстрее.

Более того, ты дебагить будешь, поэтому тебе проще один раз файл перегнать в нужный формат и все.

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 4)
Ответ на: комментарий от derlafff

cat ascii-file | tr ' ' '\n' >/dev/null

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

Sahas ★★★★☆
() автор топика
Ответ на: комментарий от Sahas

Т.е. по идее, чтение посимвольно что в питоне, что в С должно быть примерно с одной скоростью... Или я не прав?

При работе со строками третий Питон рассчитан на Юникод, тогда как в Си ты можешь читать строго побайтово. Однако, конечно, основной оверхед — создание множества объектов, скорее всего.

Попробуй PyPy.

proud_anon ★★★★★
()

берёшь(делаешь)(чё быстрей, приятней) простейшей КА по выдёргивания не пробельных последовательностей. сквозным чтением потока прочитываеш Nую читаеш(из строки) эту строку как вещественное в переменную вещественную.

в питоне тоже будет ок.

qulinxao ★★☆
()
Ответ на: комментарий от proud_anon

Попробуй PyPy.

это я на кластере развлекаюсь, а его там нету... И кстати, 3-его питона тоже, я во 2-ой всё конвертю =)

Sahas ★★★★☆
() автор топика
Ответ на: комментарий от Sahas

В общем случае - неправ, в питоне под капотом совершается куча дополнительных действий по выделению памяти для новых объектов и т.п., которые в C полностью находятся в отвественности программиста. Как раз для того, чтобы писать на питоне было быстрее и удобнее. Про то, что C быстрее Python, никто не спорит, но то, что C уделал по скорости _разработки_ Python - это неправда, на деле это Python уделал тебя.

E ★★★
()
Ответ на: комментарий от drull

Что такого-то? N-мерные массивы в первом приближении индексируются так же, как n раз вложенные списки.

Axon ★★★★★
()
Ответ на: комментарий от E

понятно, что у Python накладные расходы гораздо выше, но что касается чтения файла, там на кажый read идёт создание объекта? Или перезаписывается старый? В последнем случае, ИМХО, оверхед небольшой...

Sahas ★★★★☆
() автор топика
Последнее исправление: Sahas (всего исправлений: 1)
Ответ на: комментарий от Axon

Если data - это N-мерный массив, то

data[i]
- это (N-1)-мерный массив, а вовсе не искомое число. Конечно предполагается что N>1

drull ★☆☆☆
()
Последнее исправление: drull (всего исправлений: 2)
Ответ на: комментарий от Axon

у тя омонимия одномерного размером N и многоразмерного N размером каждого идекса 1.

т.е у тя одноэлементый с N 1ично индексами и Nэлементный с одним индексом 1..N омонимы.

qulinxao ★★☆
()

ногда происходит перевод строки

а что за программа генерит такой странный файл с данными, почему не в столбики? Вообще на таких объёмах логичнее использовать бинари формат.

WerNA ★★★★★
()
Ответ на: комментарий от Sahas

там на кажый read идёт создание объекта?

А может и нескольких. Строки каждый раз новые создаются в любом случае.

Тем более если у тебя старый Питон.

proud_anon ★★★★★
()
Ответ на: комментарий от Sahas

Одна Сатана. Попытка устроить спор на пустом месте же.

Lilly
()
Ответ на: комментарий от Sahas

Которое все проигнорировали, судя по ответам, т.к. оно теряется на фоне остальных. Но если тебе потрепаться, то, конечно, и так сойдёт :)

Deleted
()
Ответ на: комментарий от WerNA

это отдельная печальная история... такой файл генерит Fortran, а вот с бинарными данными проблема... В общем и целом, проблема в Fortran'е, и для её поиска пришлось применить другие ЯП

Sahas ★★★★☆
() автор топика
Ответ на: комментарий от Deleted

Но если тебе потрепаться, то, конечно, и так сойдёт :)

Surely :) Проблему-то я решил, а тут решил пофлудить :)

Sahas ★★★★☆
() автор топика
Ответ на: комментарий от Axon

Вот видишь, пришел кулинсао и все понятно объяснил :)

buddhist ★★★★★
()
Ответ на: комментарий от Sahas

А зачем парсить число, если ты его тут же выводишь? Тупо читай %s и сразу выводи. %s это строка символов без разделителей.

ziemin ★★
()
Ответ на: комментарий от qulinxao

Какая ещё омонимия? Двумерный массив с N элементами единичной длины - это одномерный массив с формой (1,N).

Axon ★★★★★
()
Ответ на: комментарий от ziemin

в смысле, надо написать fscanf(f, «%s »,str)? дык я же говорю, что С тоже не особо знаю, про это не знал, например, спасибо за инфу =)

Sahas ★★★★☆
() автор топика

Чисто для забавы проверь этот:

file=__ФАЙЛ_С_ЧИСЛАМИ__
result=N
buf=0
while read line; do
    set -- $line
    for num in "$@"; do
        buf=$((buf + 1))
        if [ "$buf" = "$result" ]; then
            echo "$num"
            break 3
        fi
    done
done < "$file"
Да, это построчно.

Darth_Revan ★★★★★
()
Последнее исправление: Darth_Revan (всего исправлений: 2)
Ответ на: комментарий от Darth_Revan

что-то 10 минут прошло, а оно всё там...

Тут проблема в том, что в строке может быть >1E+6 чисел, видимо, поэтому построчно читать плохо...

Sahas ★★★★☆
() автор топика
Последнее исправление: Sahas (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.