Как избежать повторной загрузки большого файла? - PullRequest
3 голосов
/ 28 января 2012

Я пытаюсь вызвать программу на Java (Stanford Chinese Word Segmenter) изнутри python.Java-программе необходимо загрузить большой (100 МБ) файл словаря (список слов для облегчения сегментации), который занимает более 12 секунд.Мне было интересно, возможно ли ускорить процесс загрузки, и, что более важно, как избежать повторной загрузки, когда мне нужно вызывать скрипт python несколько раз?

Вот соответствующая часть кода:

op = subprocess.Popen(['java',
                       '-mx2g',
                       '-cp',
                       'seg.jar',
                       'edu.stanford.nlp.ie.crf.CRFClassifier',
                       '-sighanCorporaDict',
                       'data',
                       '-testFile',
                       filename, 
                       '-inputEncoding',
                       'utf-8', 
                       '-sighanPostProcessing',
                       'true',
                       'ctb', 
                       '-loadClassifier',
                       **'./data/ctb.gz',**
                       '-serDictionary',
                       './data/dict-chris6.ser.gz',
                       '0'],
                       stdout = subprocess.PIPE,
                       stdin  = subprocess.PIPE,
                       stderr = subprocess.STDOUT,
                       )

В приведенном выше коде './data/ctb.gz' - это место, куда загружается файл списка больших слов.Я думаю, что это может быть связано с процессом, но я мало что знаю об этом.

Ответы [ 5 ]

2 голосов
/ 28 января 2012

Вы можете использовать решение для конкретной ОС здесь. Большинство современных операционных систем имеют возможность иметь раздел в памяти. Например, в Linux вы могли бы сделать

 mkfs -q /dev/ram1 8192
 mkdir -p /ramcache
 mount /dev/ram1 /ramcache

Перемещение файла в этот каталог значительно ускорит ввод / вывод

1 голос
/ 28 января 2012

Может быть много способов ускорить загрузку списка слов, но это зависит от деталей. Если IO (скорость чтения с диска) является узким местом, то простой способ может заключаться в том, чтобы сжать файл и использовать ZipInputStream для его чтения - но вам нужно будет протестировать это.

Чтобы избежать многократной загрузки, вам, вероятно, нужно поддерживать процесс Java и связываться с ним из Python через файлы или сокеты, чтобы отправлять ему команды, вместо того, чтобы фактически запускать процесс Java каждый раз из Python.

Однако оба из них требуют изменения кода Java.

0 голосов
/ 28 января 2012

Если java-программа выдает выходные данные, как только получает входные данные от filename именованного канала , и вы не можете изменить java-программу, вы можете оставить вместо этого свой скрипт Python и связаться с ним через файлы / сокеты как @ DNA, предложенные для процесса Java (та же идея, но программа Python продолжает работать).

# ...
os.mkfifo(filename)

p = Popen([..., filename, ...], stdout=PIPE)
with open(filename, 'w') as f:
     while True:
         indata = read_input() # read text to segment from files/sockets, etc
         f.write(indata)
         # read response from java process
         outdata = p.stdout.readline()# you need to figure out when to stop reading
         write_output(outdata) # write response via files/sockets, etc
0 голосов
/ 28 января 2012

Почему бы не отследить, был ли файл уже прочитан на стороне Python? Я не гениальный питон, но я уверен, что вы могли бы иметь какой-то список или карту / словарь всех файлов, которые были открыты до сих пор.

0 голосов
/ 28 января 2012

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

...