Neden std::string işlemleri gerçekleştirmek kötü?
Bir test sunucu tarafı uygulama için bir dil seçmek için birçok dilde dize işlemleri karşılaştırmak için yaptım. Sonuçları nihayet C , beni şaşırtan bir sürü çalışana kadar normal görünüyordu. Eğer herhangi bir optimizasyon cevapsız ve yardım için buraya geldim, merak ediyorum.
Test temel olarak yoğun string işlemleri, bağlamak ve arama dahil olmak üzere. Test 11.10 amd64, GCC 4.6.1 sürümü ile Ubuntu üzerinde yapılır. Makine Dell RAM ve Dört Çekirdekli İŞLEMCİ 4G ile 960, Optiplex.
(2.7.2) Python:
def test():
x = ""
limit = 102 * 1024
while len(x) < limit:
x = "X"
if x.find("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0) > 0:
print("Oh my god, this is impossible!")
print("x's length is : %d" % len(x))
test()
hangi sonucu verir:
x's length is : 104448
real 0m8.799s
user 0m8.769s
sys 0m0.008s
Java (- OpenJDK 7):
public class test {
public static void main(String[] args) {
int x = 0;
int limit = 102 * 1024;
String s="";
for (; s.length() < limit;) {
s = "X";
if (s.indexOf("ABCDEFGHIJKLMNOPQRSTUVWXYZ") > 0)
System.out.printf("Find!\n");
}
System.out.printf("x's length = %d\n", s.length());
}
}
hangi sonucu verir:
x's length = 104448
real 0m50.436s
user 0m50.431s
sys 0m0.488s
Javascript (Nodejs 0.6.3)
function test()
{
var x = "";
var limit = 102 * 1024;
while (x.length < limit) {
x = "X";
if (x.indexOf("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0) > 0)
console.log("OK");
}
console.log("x's length = " x.length);
}();
hangi sonucu verir:
x's length = 104448
real 0m3.115s
user 0m3.084s
sys 0m0.048s
C (g -Ofast)
Daha iyi bir Python ya da Java daha performas Nodejs şaşırtıcı değil. Ama libstdc gerçekten bana sürpriz olan Nodejs, çok daha iyi performans vereceğini bekliyordum.
#include <iostream>
#include <string>
using namespace std;
void test()
{
int x = 0;
int limit = 102 * 1024;
string s("");
for (; s.size() < limit;) {
s = "X";
if (s.find("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0) != string::npos)
cout << "Find!" << endl;
}
cout << "x's length = " << s.size() << endl;
}
int main()
{
test();
}
hangi sonucu verir:
x length = 104448
real 0m5.905s
user 0m5.900s
sys 0m0.000s
Özet
TAMAM, şimdi özetine bakalım:
- Nodejs javascript(V8): s 3.1
- CPython 2.7.2 üzerinde Python : s 8.8
- Libstdc ile C : nin 5.9
- OpenJDK 7 Java: 50.4
Şaşırtıcı! Denedim "-O2, -O3" C ama yardım ettiğini kaydetti. C sadece V8 ve CPython bile daha kötü javascript P performans gibi görünüyor. Eğer GCC bazı optimizasyon kaçırmış olsaydım bana açıklayabilir ya da bu yanlış bir bilgidir? Çok teşekkür ederim.
CEVAP
std::string
kötü yapan değil, (C sevmediğim kadar ), dize işleme bu kadar ağır, bu diğer diller için optimize edilmiş.
Dize performans karşılaştırmalar yanıltıcı, ve eğer sadece daha fazla temsil etmek için tasarlanmış ise küstahça.
Python string objects are completely implemented in C, ve gerçekten de Python 2.7,numerous optimizations unicode dizeleri ve bayt arasında ayrılık olmaması nedeniyle var olan bir gerçeği biliyorum. Python 3 bu testi geçtin.x çok yavaş bulacaksınız.
Javascript ağır optimize edilmiş çok sayıda uygulamaları vardır. Dize işleme mükemmel beklendiği üzere burada.
Java sonucu uygun dize işleme veya başka bir kötü durum nedeniyle olabilir. Java uzmanı olarak adım ve bir kaç değişiklik ile bu test düzeltebileceğini umuyorum.
C örnek olarak, performansını biraz Python sürümü aşmak için beklerdim. Aynı işlemleri, daha az sözlü yükü ile geliyor. Bu sonuçları da yansıyor. s.reserve(limit);
ile test önceki tahsisat yükü kaldırmak istiyorsunuz.
Tek dil tek tarafı test olduğunu tekrar edeceğimuygulamaları. Bu test sonuçları genel dil hızını yansıtır.
Ne kadar saçma böyle sidik yarıştırmaya olabilir göstermek için C'yi gördüm:
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
void test()
{
int limit = 102 * 1024;
char s[limit];
size_t size = 0;
while (size < limit) {
s[size ] = 'X';
if (memmem(s, size, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26)) {
fprintf(stderr, "zomg\n");
return;
}
}
printf("x's length = %zu\n", size);
}
int main()
{
test();
return 0;
}
Zamanlama:
matt@stanley:~/Desktop$ time ./smash
x's length = 104448
real 0m0.681s
user 0m0.680s
sys 0m0.000s
Neden &; ad std quot;" kötü olara...
Neden&; dizi yineleme için... "* o kad...
Python katılın, neden dize.liste yerin...
Neden Ruby Hariç => e `kurtarmak iç...
Neden JavaScript eval fonksiyonu kötü ...