Сейчас я пытаюсь преобразовать большое количество двоичных файлов точек в формате широты и долготы в текстовый декартовый формат ECEF (x, y, z). Проблема сейчас в том, что процесс очень, очень, очень медленный.
У меня есть более 100 гигабайт этого материала для прохождения, и может поступать больше данных. Я хотел бы сделать этот фрагмент кода максимально быстрым.
Прямо сейчас мой код выглядит примерно так:
import mmap
import sys
import struct
import time
pointSize = 41
def getArguments():
if len(sys.argv) != 2:
print """Not enough arguments.
example:
python tllargbin_reader.py input_filename.tllargbin output_filename
"""
return None
else:
return sys.argv
print getArguments()
def read_tllargbin(filename, outputCallback):
f = open(filename, "r+")
map = mmap.mmap(f.fileno(),0)
t = time.clock()
if (map.size() % pointSize) != 0:
print "File size not aligned."
#return
for i in xrange(0,map.size(),pointSize):
data_list = struct.unpack('=4d9B',map[i:i+pointSize])
writeStr = formatString(data_list)
if i % (41*1000) == 0:
print "%d/%d points processed" % (i,map.size())
print "Time elapsed: %f" % (time.clock() - t)
map.close()
def generate_write_xyz(filename):
f = open(filename, 'w', 128*1024)
def write_xyz(writeStr):
f.write(writeStr)
return write_xyz
def formatString(data_list):
return "%f %f %f" % (data_list[1], data_list[2],data_list[3])
args = getArguments()
if args != None:
read_tllargbin(args[1],generate_write_xyz("out.xyz"))
convertXYZ () - это в основном формула преобразования:
http://en.wikipedia.org/wiki/Geodetic_system
Мне было интересно, будет ли быстрее читать вещи кусками ~ 4 МБ одним потоком, помещать их в ограниченный буфер, иметь другой поток для преобразования в строковый формат и иметь последний поток, записывающий строку обратно в файл на другом жестком диске. Я мог бы прыгать пистолет, хотя ...
Я сейчас использую python для тестирования, но я бы не стал отказываться от переключения, если бы мог быстрее работать с этими файлами.
Любые предложения будут великолепны. Спасибо
EDIT:
Я снова профилировал код с помощью cProfile и на этот раз разделил формат строки и io. Похоже, что меня на самом деле убивает формат строки ... Вот отчет профилировщика
20010155 function calls in 548.993 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 548.993 548.993 <string>:1(<module>)
1 0.016 0.016 548.991 548.991 tllargbin_reader.py:1(<module>)
1 24.018 24.018 548.955 548.955 tllargbin_reader.py:20(read_tllargbin)
1 0.000 0.000 0.020 0.020 tllargbin_reader.py:36(generate_write_xyz)
10000068 517.233 0.000 517.233 0.000 tllargbin_reader.py:42(formatString)
2 0.000 0.000 0.000 0.000 tllargbin_reader.py:8(getArguments)
10000068 6.684 0.000 6.684 0.000 {_struct.unpack}
1 0.002 0.002 548.993 548.993 {execfile}
2 0.000 0.000 0.000 0.000 {len}
1 0.065 0.065 0.065 0.065 {method 'close' of 'mmap.mmap' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {method 'fileno' of 'file' objects}
10003 0.955 0.000 0.955 0.000 {method 'size' of 'mmap.mmap' objects}
2 0.020 0.010 0.020 0.010 {open}
2 0.000 0.000 0.000 0.000 {time.clock}
Есть ли более быстрый способ форматирования строк?