Python ve C++ arasındaki performans denemelerini araştırırken, çoğunlukla dilsiz bir alt dizgi eşleşmesine odaklanan küçük bir örnek oluşturdum.Dize eşleştirme performansı: gcc versus CPython
using std::string;
std::vector<string> matches;
std::copy_if(patterns.cbegin(), patterns.cend(), back_inserter(matches),
[&fileContents] (const string &pattern) { return fileContents.find(pattern) != string::npos; });
yukarıdaki -o3 ile inşa edilmiştir:
İşte alakalı C++ olduğunu.
def getMatchingPatterns(patterns, text):
return filter(text.__contains__, patterns)
İkisi desenleri ve giriş dosyasının large-ish set almak ve dilsiz alt dize aramayı kullanarak dosyada bulunan olanlara kalıplarının listeyi filtre:
Ve burada Python .
sürümleri şunlardır:
- gcc - 4.8.2 (Ubuntu) ve 4.9.2 (cygwin)
- piton - 2.7.6 (Ubuntu) ve 2.7.8 (cygwin)
Şaşırtıcı olan şey performanstır. Ben hem düşük spec Ubuntu koştum ve Python yaklaşık% 20 daha hızlı oldu. Cygwin ile orta spec PC'de aynı - Python iki kat daha hızlı. Profiler, döngülerin% 99'unun dize eşlemede harcandığını gösterir (dizi kopyalama ve liste anlamaları önemsizdir).
Açıkçası, Python uygulaması doğal C'dür ve C++ ile aynı olması beklenir, ancak bunu hızlı beklemezdim.
Gcc ile ilgili olarak ilgili CPython optimizasyonları hakkında herhangi bir fikir en çok hoş karşılanır.
Referans için, burada tam örnekler.
Python:
import sys
def getMatchingPatterns(patterns, text):
return filter(text.__contains__, patterns)
def serialScan(filenames, patterns):
return zip(filenames, [getMatchingPatterns(patterns, open(filename).read()) for filename in filenames])
if __name__ == "__main__":
with open(sys.argv[1]) as filenamesListFile:
filenames = filenamesListFile.read().split()
with open(sys.argv[2]) as patternsFile:
patterns = patternsFile.read().split()
resultTuple = serialScan(filenames, patterns)
for filename, patterns in resultTuple:
print ': '.join([filename, ','.join(patterns)])
C++: girişler sadece 50K HTLMs bir dizi (tümü her test, hiçbir özel önbelleğe alma içinde diskten okuma) almak
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
using MatchResult = unordered_map<string, vector<string>>;
static const size_t PATTERN_RESERVE_DEFAULT_SIZE = 5000;
MatchResult serialMatch(const vector<string> &filenames, const vector<string> &patterns)
{
MatchResult res;
for (auto &filename : filenames)
{
ifstream file(filename);
const string fileContents((istreambuf_iterator<char>(file)),
istreambuf_iterator<char>());
vector<string> matches;
std::copy_if(patterns.cbegin(), patterns.cend(), back_inserter(matches),
[&fileContents] (const string &pattern) { return fileContents.find(pattern) != string::npos; });
res.insert(make_pair(filename, std::move(matches)));
}
return res;
}
int main(int argc, char **argv)
{
vector<string> filenames;
ifstream filenamesListFile(argv[1]);
std::copy(istream_iterator<string>(filenamesListFile), istream_iterator<string>(),
back_inserter(filenames));
vector<string> patterns;
patterns.reserve(PATTERN_RESERVE_DEFAULT_SIZE);
ifstream patternsFile(argv[2]);
std::copy(istream_iterator<string>(patternsFile), istream_iterator<string>(),
back_inserter(patterns));
auto matchResult = serialMatch(filenames, patterns);
for (const auto &matchItem : matchResult)
{
cout << matchItem.first << ": ";
for (const auto &matchString : matchItem.second)
cout << matchString << ",";
cout << endl;
}
}
@SylvainLeroux - Ben profiler çalıştıran,% 99% gerçek eşleme, std :: string :: find 've' string .__ includes__' harcanıyor. '' '' '(Multiple multiple''' string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string string ((((((((((((((((((((((((((((((((((but but but but but but but but but but but but but but but but but but but but but but but but but but but but but but but but but but but ins ins ins ins ins ins ins ins ins ins ins ins ins but ins but but but but but but but but but but but but – RomanK
Bu "Python nasıl bu kadar hızlı olabilir" sorusu değil, "C++ nasıl bu kadar yavaş olabilir" sorusu –
Dosya önbelleğini hariç tuttunuz mu? gcc sürümü? Bir MCVE sağlayabilir misiniz? – edmz