W jaki sposób yield
implementuje wzór lazy loading
?Jak wydajność realizuje wzór leniwego ładowania?
Odpowiedz
Wydajność plonów nie dociera do kodu, dopóki nie będzie potrzebna.
Na przykład, kod:
public IEnumerable<int> GetInts()
{
yield return 1;
yield return 2;
yield return 3;
}
rzeczywiście kompilacji do zagnieżdżonej klasy realizujący IEnumerable<int>
i ciało GetInts()
powróci wystąpienia tej klasy.
Korzystanie reflektora widać:
public IEnumerable<int> GetInts()
{
<GetInts>d__6d d__d = new <GetInts>d__6d(-2);
d__d.<>4__this = this;
return d__d;
}
Edit - dodając więcej informacji o GetInts
realizacji:
Droga ta realizacja sprawia, że jest leniwy oparty jest na metodzie Enumerator
MoveNext()
. Gdy generowana jest wyliczalna klasa zagnieżdżona (<GetInts>d__6d
w przykładzie), ma ona stan i dla każdego stanu jest połączona wartość (jest to prosty przypadek, w bardziej zaawansowanych przypadkach wartość będzie oceniana, gdy kod osiągnie stan). Jeśli spojrzymy w kodzie MoveNext()
z <GetInts>d__6d
zobaczymy stan:
private bool MoveNext()
{
switch (this.<>1__state)
{
case 0:
this.<>1__state = -1;
this.<>2__current = 1;
this.<>1__state = 1;
return true;
case 1:
this.<>1__state = -1;
this.<>2__current = 2;
this.<>1__state = 2;
return true;
case 2:
this.<>1__state = -1;
this.<>2__current = 3;
this.<>1__state = 3;
return true;
case 3:
this.<>1__state = -1;
break;
}
return false;
}
Gdy wyliczający jest proszony dla bieżącego obiektu zwraca obiekt, który jest podłączony do obecnego stanu.
W celu wykazania, że kod jest oceniany tylko wtedy, gdy jest to wymagane można spojrzeć na ten przykład:
[TestFixture]
public class YieldExample
{
private int flag = 0;
public IEnumerable<int> GetInts()
{
yield return 1;
flag = 1;
yield return 2;
flag = 2;
yield return 3;
flag = 3;
}
[Test]
public void Test()
{
int expectedFlag = 0;
foreach (var i in GetInts())
{
Assert.That(flag, Is.EqualTo(expectedFlag));
expectedFlag++;
}
Assert.That(flag, Is.EqualTo(expectedFlag));
}
}
Mam nadzieję, że nieco bardziej wyraźne. Polecam przyjrzeć się kodowi z Reflectorem i obserwować skompilowany kod podczas zmiany kodu "yield".
Jeśli chcesz wiedzieć więcej o tym, co robi kompilator podczas korzystania yield return
, sprawdź ten artykuł Jon Skeet: Iterator block implementation details
Przekierowanie Briljant, faktycznie. +1 – peSHIr
Zasadniczo iteratory implementated za pomocą yield
oświadczenia są kompilowane do klasy, która implementuje state machine.
Jeśli nigdy nie będziesz foreach
(= powtórz i używaj) zwróconego IEnumerable<T>
, kod nigdy nie zostanie faktycznie wykonany. A jeśli to zrobisz, zostanie wykonany tylko minimalny kod potrzebny do określenia następnej wartości do zwrócenia, tylko w celu wznowienia wykonywania, gdy zażąda kolejnej wartości.
Możesz zobaczyć to zachowanie, gdy pojedynczy krok takiego kodu w debugerze. Spróbuj przynajmniej raz: myślę, że to jest pouczające, aby zobaczyć to krok po kroku.
- 1. Symfony2 czas ładowania i wydajność
- 2. Jak CppUnit realizuje test wyjątek
- 3. Dlaczego struktura encji potrzebuje ICollection do leniwego ładowania?
- 4. Pierwsza próba leniwego ładowania (opóźnianie ładowania osadzonych filmów w YouTube) - jak mogę to zrobić z większą wdziękiem?
- 5. Hibernate JPA: Jak kontrolować zachowanie "Not-Found" podczas leniwego ładowania relacji ManyToOne?
- 6. Jak wyszukiwać dane dla Primefaces dataTable za pomocą leniwego ładowania i stronicowania
- 7. Wzór do porządkowania i ładowania CSS w Angular.js
- 8. Guice: Unikaj leniwego wtrysku
- 9. Potwierdzanie leniwego oceniania
- 10. Czy istnieje parametryczna wersja leniwego `ByteString`?
- 11. Dlaczego Djinn nie realizuje typowych funkcji monadycznych?
- 12. NHibernate: „zbiór nie został przetworzony przez flush()” spowodowane przez leniwego ładowania emisji
- 13. Sprawdzanie istnienia leniwego załadowanego dziecka bez pobierania/ładowania w Fluent NHibernate
- 14. Obowiązujący wzór Wzór
- 15. NHibernate - dostęp do identyfikatora powiązanego obiektu bez leniwego ładowania całego obiektu
- 16. Dynamiczne generowanie obrazu jest wymagane dwukrotnie podczas korzystania z leniwego ładowania jquery w przeglądarce Google Chrome
- 17. Konfiguracja Webpack 2 do drżenia drzewa i leniwego ładowania z System.import w projekcie React
- 18. Jak analizować wzór PCRE?
- 19. Kiedy należy unikać używania funkcji ładowania w systemie NHibernate?
- 20. Leniwe szablony ładowania w Meteoru
- 21. Sposób na osiągnięcie leniwego oceniania w C++
- 22. Jak zmierzyć czas ładowania w Angular2?
- 23. Prosty sposób testowania właściwości leniwego obciążenia
- 24. wzór pracy zwrotu plonu
- 25. Powtarzalny wzór
- 26. Zastosowanie zmienna jak RegEx wzór
- 27. Najlepszy wzór dla następnego scenariusza
- 28. Jak poprawić wydajność SQLAlchemy?
- 29. Jak poprawić wydajność Webpack?
- 30. Jak wydajność jest przeliczalna?
@ Eliada: proszę podać więcej szczegółów na temat GetInts(). –
@masoud ramezani, dodano więcej informacji o klasie zagnieżdżonej GetInts. – Elisha
Dziękuję za odpowiedź. –