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
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.
- Bluebird kendini talks about it here Petka.
- Vyacheslav Egorov These slides de bahseder.
- This question and its accepted answer de iliÅŸkilidir.
- This slightly outdated article hala seni nesneleri v8 saklanır hakkında iyi bir fikir verebilecek oldukça iyi bir okuma.
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.
Nasıl kullanıcı tanımlı bir işlev açık...
&Quot;ssh" serseri; tam olarak ne ...
Nasıl "nesne yapar.yeni" iş?...
Nasıl olabilirdi zaman&; nesne başvuru...
jquery UI sıralanabilir: nasıl "t...