私は直接CのAPI(拡張機能)関数をインポートするために管理していなかったが、私は、インポートするためにはPythonを使用io
グローバル組み込み関数へのリンク/参照持つモジュール、open
などをio.open()
。
bool hasfinished;
const char* filepath;
long long int linecount;
std::deque<PyObject*> linecache;
PyObject* iomodule;
PyObject* openfile;
PyObject* fileiterator;
FastFile(const char* filepath) : hasfinished(false), filepath(filepath), linecount(0) {
iomodule = PyImport_ImportModule( "io" );
if( iomodule == NULL ) {
std::cerr << "ERROR: FastFile failed to import the io module '"
<< filepath << "')!" << std::endl;
PyErr_Print();
return;
}
PyObject* openfunction = PyObject_GetAttrString( iomodule, "open" );
if( openfunction == NULL ) {
std::cerr << "ERROR: FastFile failed get the io module open function '"
<< filepath << "')!" << std::endl;
PyErr_Print();
return;
}
openfile = PyObject_CallFunction( openfunction, "s", filepath,
"s", "r", "i", -1, "s", "UTF8", "s", "replace" );
PyObject* iterfunction = PyObject_GetAttrString( openfile, "__iter__" );
Py_DECREF( openfunction );
if( iterfunction == NULL ) {
std::cerr << "ERROR: FastFile failed get the io module iterator function '"
<< filepath << "')!" << std::endl;
PyErr_Print();
return;
}
PyObject* openfileresult = PyObject_CallObject( iterfunction, NULL );
Py_DECREF( iterfunction );
if( openfileresult == NULL ) {
std::cerr << "ERROR: FastFile failed get the io module iterator object '"
<< filepath << "')!" << std::endl;
PyErr_Print();
return;
}
fileiterator = PyObject_GetAttrString( openfile, "__next__" );
Py_DECREF( openfileresult );
if( fileiterator == NULL ) {
std::cerr << "ERROR: FastFile failed get the io module iterator object '"
<< filepath << "')!" << std::endl;
PyErr_Print();
return;
}
}
~FastFile() {
this->close();
Py_XDECREF( iomodule );
Py_XDECREF( openfile );
Py_XDECREF( fileiterator );
for( PyObject* pyobject : linecache ) {
Py_DECREF( pyobject );
}
}
void close() {
PyObject* closefunction = PyObject_GetAttrString( openfile, "close" );
if( closefunction == NULL ) {
std::cerr << "ERROR: FastFile failed get the close file function for '"
<< filepath << "')!" << std::endl;
PyErr_Print();
return;
}
PyObject* closefileresult = PyObject_CallObject( closefunction, NULL );
Py_DECREF( closefunction );
if( closefileresult == NULL ) {
std::cerr << "ERROR: FastFile failed close open file '"
<< filepath << "')!" << std::endl;
PyErr_Print();
return;
}
Py_DECREF( closefileresult );
}
bool _getline() {
// Fix StopIteration being raised multiple times because
// _getlines is called multiple times
if( hasfinished ) { return false; }
PyObject* readline = PyObject_CallObject( fileiterator, NULL );
if( readline != NULL ) {
linecount += 1;
linecache.push_back( readline );
return true;
}
// PyErr_Print();
PyErr_Clear();
hasfinished = true;
return false;
}
これをでコンパイルするとVisual Studio Compiler
、このコードを使用して次のパフォーマンスが得られます。
print( 'fastfile_time %.2f%%, python_time %.2f%%' % (
fastfile_time/python_time, python_time/fastfile_time ), flush=True )
$ python3 fastfileperformance.py Python timedifference 0:00:00.985254 FastFile timedifference 0:00:01.084283 fastfile_time 1.10%, python_time 0.91% = 0.09% $ python3 fastfileperformance.py
Python timedifference 0:00:00.979861
FastFile timedifference 0:00:01.073879
fastfile_time 1.10%, python_time 0.91% = 0.09%
$ python3 fastfileperformance.py Python timedifference 0:00:00.990369 FastFile timedifference 0:00:01.086416 fastfile_time 1.10%, python_time 0.91% = 0.09% $ python3 fastfileperformance.py
Python timedifference 0:00:00.975223
FastFile timedifference 0:00:01.077857
fastfile_time 1.11%, python_time 0.90% = 0.10%
$ python3 fastfileperformance.py Python timedifference 0:00:00.988327 FastFile timedifference 0:00:01.085866 fastfile_time 1.10%, python_time 0.91% = 0.09% $ python3 fastfileperformance.py
Python timedifference 0:00:00.971848
FastFile timedifference 0:00:01.087894
fastfile_time 1.12%, python_time 0.89% = 0.11%
$ python3 fastfileperformance.py Python timedifference 0:00:00.968116 FastFile timedifference 0:00:01.079976 fastfile_time 1.12%, python_time 0.90% = 0.10% $ python3 fastfileperformance.py
Python timedifference 0:00:00.980856
FastFile timedifference 0:00:01.068325
fastfile_time 1.09%, python_time 0.92% = 0.08%
しかし、でコンパイルするとg++
、次のパフォーマンスが得られます。
$ /bin/python3.6 fastfileperformance.py Python timedifference 0:00:00.703964 FastFile timedifference 0:00:00.813478 fastfile_time 1.16%, python_time 0.87% = 0.13% $ /bin/python3.6 fastfileperformance.py
Python timedifference 0:00:00.703432
FastFile timedifference 0:00:00.809531
fastfile_time 1.15%, python_time 0.87% = 0.13%
$ /bin/python3.6 fastfileperformance.py Python timedifference 0:00:00.705319 FastFile timedifference 0:00:00.814130 fastfile_time 1.15%, python_time 0.87% = 0.13% $ /bin/python3.6 fastfileperformance.py
Python timedifference 0:00:00.711852
FastFile timedifference 0:00:00.837132
fastfile_time 1.18%, python_time 0.85% = 0.15%
$ /bin/python3.6 fastfileperformance.py Python timedifference 0:00:00.695033 FastFile timedifference 0:00:00.800901 fastfile_time 1.15%, python_time 0.87% = 0.13% $ /bin/python3.6 fastfileperformance.py
Python timedifference 0:00:00.694661
FastFile timedifference 0:00:00.796754
fastfile_time 1.15%, python_time 0.87% = 0.13%
$ /bin/python3.6 fastfileperformance.py Python timedifference 0:00:00.699377 FastFile timedifference 0:00:00.816715 fastfile_time 1.17%, python_time 0.86% = 0.14% $ /bin/python3.6 fastfileperformance.py
Python timedifference 0:00:00.699229
FastFile timedifference 0:00:00.818774
fastfile_time 1.17%, python_time 0.85% = 0.15%