SORU
29 Kasım 2011, Salı


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
29 Kasım 2011, Salı


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

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • KRQE

    KRQE

    6 AĞUSTOS 2007
  • Santozz Yazz

    Santozz Yazz

    23 Mart 2014
  • soyacincautv

    soyacincautv

    14 NİSAN 2010