Nasıl Bluebird'ler açıklama yapar.toFastProperties işlev, nesnenin'un özellikleri "hızlı"? | Netgez.com
SORU
28 Temmuz 2014, PAZARTESÄ°


Nasıl Bluebird'ler açıklama yapar.toFastProperties işlev, nesnenin'un özellikleri "hızlı"?

Bluebird util.js file, aşağıdaki işlevi vardır:

function toFastProperties(obj) {
    /*jshint -W027*/
    function f() {}
    f.prototype = obj;
    ASSERT("%HasFastProperties", true, obj);
    return f;
    eval(obj);
}

Nedense, o yüzden emin değilim dönüş işlevi, ardından bir açıklama var.

İyi yazar, JSHint bu konuda uyarı Susturuldu vardı kasıtlı olarak, bu gibi görünüyor:

''''. Döndükten sonra eval ulaşılamaz (W027)

Tam olarak bu fonksiyon ne yapar? util.toFastProperties gerçekten bir nesnenin özellikleri yapar ""? daha hızlı

Kaynak kodu herhangi bir yorum ya da sorunları kendi listesinde bir açıklama Bluebird. GitHub depo ile arama yaptım, ama bulamadım.

CEVAP
28 Temmuz 2014, PAZARTESÄ°


Haydi, ne yaptığını ve bunu daha hızlı ve neden çalıştığını neden ilk tartışın.

Ne işe yaradığını biliyorum

V8 motor iki nesne temsilleri kullanır:

  • Sözlük moduhangi nesneyi anahtar olarak saklanır - - hash map bir deÄŸer olarak haritalar.
  • Hızlı moduhangi hesaplama özelliÄŸi eriÅŸim dahil yok yok structs gibi saklı olan. -

Burada hız farkı gösteren a simple demo. Burada yavaş sözlük moduna nesneleri zorlamak için delete deyimi kullanırız.

Motoru mümkün olduğunda ve genel olarak mülkiyet erişim çok yapılır Hızlı modu kullanmaya çalışır - ancak bazen sözlük moduna atılmış olur. Sözlük modunda olmak genellikle Hızlı modu nesneleri koymak için arzu edilir, bu yüzden büyük bir başarım var.

Bu hack sözlük modundan hızlı moduna nesne zorlamak için tasarlanmıştır.

Daha hızlı bu yüzden

JavaScript prototip genellikle fonksiyonları birçok örnekleri arasında paylaşılan mağaza ve nadiren çok dinamik olarak değiştirin. Çok arzu fast modunda ekstra ceza her zaman kaçınmak gerekir, bu nedenle bir işlev olarak adlandırılır.

Bu v8 seve seve her nesne yapıcı olarak bu fonksiyonla oluşturulan tarafından paylaşılan olacak beri hızlı modda işlevleri .prototype özelliği olan nesneler koyun. Bu genellikle zeki ve çekici bir optimizasyon.

Nasıl çalışır

Bakalım ilk kod geçmesi ve her satırın ne olduğunu:

function toFastProperties(obj) {
    /*jshint -W027*/ // suppress the "unreachable code" error
    function f() {} // declare a new function
    f.prototype = obj; // assign obj as its prototype to trigger the optimization
    // assert the optimization passes to prevent the code from breaking in the
    // future in case this optimization breaks:
    ASSERT("%HasFastProperties", true, obj); // requires the "native syntax" flag
    return f; // return it
    eval(obj); // prevent the function from being optimized through dead code 
               // elimination or further optimizations. This code is never  
               // reached but even using eval in unreachable code causes v8
               // to not optimize functions.
}

Bilmiyoruzvarkendimizi v8 bu optimizasyon mu iddia kodunu bulmak için, 36* *yerine:

// Adding this many properties makes it slow.
assertFalse(%HasFastProperties(proto));
DoProtoMagic(proto, set__proto__);
// Making it a prototype makes it fast again.
assertTrue(%HasFastProperties(proto));

Okuma ve bu test çalışan bu optimizasyon gerçekten v8 çalıştığını bize gösterir. Ancak nasıl görmek güzel olurdu.

Eğer objects.cc kontrol ettiğimizde aşağıdaki fonksiyon (L9925) bulabiliriz:

void JSObject::OptimizeAsPrototype(Handle<JSObject> object) {
  if (object->IsGlobalObject()) return;

  // Make sure prototypes are fast objects and their maps have the bit set
  // so they remain fast.
  if (!object->HasFastProperties()) {
    MigrateSlowToFast(object, 0);
  }
}

Şimdi, JSObject::MigrateSlowToFast sadece açık bir Sözlük alır ve hızlı V8 bir nesneye dönüştürür. Değerli bir okuma ve v8 nesne iç içine ilginç bir fikir ama bu konu burada değil. Ben hala iyi bir yol v8 nesneler hakkında bilgi edinmek için bu kadar sıcak that you read it here tavsiye ederim.

Eğer dışarı objects.cc SetPrototype kontrol ettiğimizde çizgi 12231 denir görebilirsiniz:

if (value->IsJSObject()) {
    JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
}

Sırayla .prototype = ile ne olsun ki FuntionSetPrototype denir.

__proto__ = .setPrototypeOf yapmak da işe yarardı ama bu lafı kodu burada basitleştirmek için yani Netscape 7'den beri tüm tarayıcılarda ES6 fonksiyonları ve Bluebird çalışır. Eğer .setPrototypeOf kontrol ediyoruz, örneğin:

// ES6 section 19.1.2.19.
function ObjectSetPrototypeOf(obj, proto) {
  CHECK_OBJECT_COERCIBLE(obj, "Object.setPrototypeOf");

  if (proto !== null && !IS_SPEC_OBJECT(proto)) {
    throw MakeTypeError("proto_object_or_null", [proto]);
  }

  if (IS_SPEC_OBJECT(obj)) {
    %SetPrototype(obj, proto); // MAKE IT FAST
  }

  return obj;
}

DoÄŸrudan Object:

InstallFunctions($Object, DONT_ENUM, $Array(
...
"setPrototypeOf", ObjectSetPrototypeOf,
...
));

- Kod Petka yolunu çıplak metal yazdı yürüdük. Bu güzel oldu.

Yasal Uyarı:

Bu tüm uygulama detay olduÄŸunu unutmayın. Petka gibi insanlar optimizasyon ucube. Her zaman erken optimizasyonu hatırla tüm kötülüklerin — oranında. Bluebird bu performans kesmek çok ÅŸey kazanır çok çok çok temel mu - geri olduÄŸunca hızlı olmak kolay deÄŸil. Sananadirenbir kütüphane güç yok bu kod gibi bir ÅŸeyler yapmak zorunda.

Bunu PaylaÅŸ:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VÄ°DEO

Rastgele Yazarlar

  • ChasesAndCrashes

    ChasesAndCra

    31 Temmuz 2009
  • SelmerSaxMan

    SelmerSaxMan

    24 HAZÄ°RAN 2006
  • The Onion

    The Onion

    14 Mart 2006