第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

悖論:為什么收益率回報比這里列出的更快

悖論:為什么收益率回報比這里列出的更快

C#
慕尼黑8549860 2022-06-18 17:09:01
人們已經(jīng)無數(shù)次證明,那yield return比list.但是,當(dāng)我嘗試基準(zhǔn)測試時,得到了相反的結(jié)果:Results:TestYield: Time =1.19 secTestList : Time =4.22 sec在這里,List 慢了 400%。無論大小都會發(fā)生這種情況。這是沒有意義的。IEnumerable<int> CreateNumbers() //for yield{    for (int i = 0; i < Size; i++) yield return i;}IEnumerable<int> CreateNumbers() //for list{    var list = new List<int>();    for (int i = 0; i < Size; i++) list.Add(i);    return list;}以下是我使用它們的方式:foreach (var value in CreateNumbers()) sum += value;我使用所有正確的基準(zhǔn)規(guī)則來避免結(jié)果沖突,所以這不是問題。如果你看到底層代碼,yield return它是一個狀態(tài)機可憎,但它更快。為什么?編輯:所有答案都被復(fù)制,確實產(chǎn)量比列表快。New Results With Size set on constructor:TestYield: Time =1.001TestList: Time =1.403From a 400% slower difference, down to 40% slower difference.然而,這些見解令人心碎。這意味著所有那些從 1960 年起使用 list 作為默認(rèn)集合的程序員都是錯誤的,應(yīng)該被解雇(解雇),因為他們沒有使用最好的工具來解決這種情況(yield)。答案認(rèn)為,收益率應(yīng)該更快,因為它沒有實現(xiàn)。1)我不接受這個邏輯。Yield 背后有內(nèi)部邏輯,它不是“理論模型”,而是編譯器構(gòu)造。因此,它會在消費時自動實現(xiàn)。我不接受它“沒有實現(xiàn)”的論點,因為成本已經(jīng)在使用時支付。2)如果船可以走海路,而老婦人不行,你不能要求船“走陸路”。正如你在這里對列表所做的那樣。如果一個列表需要具體化,而 yield 不需要,那不是“產(chǎn)量問題”,而是一個“特性”。不應(yīng)僅僅因為它有更多用途而在測試中懲罰產(chǎn)量。3)我在這里爭論的是,如果您知道整個 SET將被消耗,那么測試的目的是找到“最快的集合”來消耗/返回方法返回的結(jié)果。yield 是否成為從方法返回列表參數(shù)的新“事實上的標(biāo)準(zhǔn)”。Edit2:如果我使用純內(nèi)聯(lián)數(shù)組,它會獲得與 Yield 相同的性能。Test 3:TestYield: Time =0.987TestArray: Time =0.962TestList: Time =1.516int[] CreateNumbers(){    var list = new int[Size];    for (int i = 0; i < Size; i++) list[i] = i;    return list;}因此,yield 會自動內(nèi)聯(lián)到數(shù)組中。列表不是。
查看完整描述

2 回答

?
米琪卡哇伊

TA貢獻1998條經(jīng)驗 獲得超6個贊

如果您使用產(chǎn)量測量版本而不具體化列表,它將比其他版本具有優(yōu)勢,因為它不必分配和調(diào)整大列表的大小(以及觸發(fā) GC)。


根據(jù)您的編輯,我想添加以下內(nèi)容:


但是,請記住,從語義上講,您正在查看兩種不同的方法。一個產(chǎn)生一個集合。它的大小是有限的,您可以存儲對集合的引用、更改其元素并共享它。


另一個產(chǎn)生一個序列。它可能是無限的,每次迭代它都會得到一個新副本,并且它后面可能有也可能沒有集合。


它們不是同一件事。編譯器不會創(chuàng)建集合來實現(xiàn)序列。如果您通過在幕后實現(xiàn)集合來實現(xiàn)序列,您將看到與使用列表的版本相似的性能。


BenchmarkDotNet 默認(rèn)情況下不允許您對延遲執(zhí)行進行計時,因此您必須構(gòu)建一個使用我在下面所做的方法的測試。我通過 BenchmarkDotNet 運行它并得到以下結(jié)果。


       Method |     Mean |    Error |   StdDev | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op |

------------- |---------:|---------:|---------:|------------:|------------:|------------:|--------------------:|

 ConsumeYield | 475.5 us | 7.010 us | 6.214 us |           - |           - |           - |                40 B |

  ConsumeList | 958.9 us | 7.271 us | 6.801 us |    285.1563 |    285.1563 |    285.1563 |           1049024 B |

注意分配。在某些情況下,這可能會有所不同。


我們可以通過分配正確的大小列表來抵消一些分配,但最終這不是蘋果對蘋果的比較。下面的數(shù)字。


       Method |     Mean |     Error |    StdDev | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op |

------------- |---------:|----------:|----------:|------------:|------------:|------------:|--------------------:|

 ConsumeYield | 470.8 us |  2.508 us |  2.346 us |           - |           - |           - |                40 B |

  ConsumeList | 836.2 us | 13.456 us | 12.587 us |    124.0234 |    124.0234 |    124.0234 |            400104 B |

代碼如下。


[MemoryDiagnoser]

public class Test

{

    static void Main(string[] args)

    {

        var summary = BenchmarkRunner.Run<Test>();

    }


    public int Size = 100000;


    [Benchmark]

    public int ConsumeYield()

    {

        var sum = 0;

        foreach (var x in CreateNumbersYield()) sum += x;

        return sum;

    }


    [Benchmark]

    public int ConsumeList()

    {

        var sum = 0;

        foreach (var x in CreateNumbersList()) sum += x;

        return sum;

    }


    public IEnumerable<int> CreateNumbersYield() //for yield

    {

        for (int i = 0; i < Size; i++) yield return i;

    }


    public IEnumerable<int> CreateNumbersList() //for list

    {

        var list = new List<int>();

        for (int i = 0; i < Size; i++) list.Add(i);

        return list;

    }

}


查看完整回答
反對 回復(fù) 2022-06-18
?
HUH函數(shù)

TA貢獻1836條經(jīng)驗 獲得超4個贊

您必須考慮以下幾點:

  • List<T>消耗內(nèi)存,但您可以一次又一次地迭代它而無需任何額外資源。為了達到同樣的效果yield,您需要通過 實現(xiàn)序列ToList()

  • 生產(chǎn)時最好設(shè)置容量List<T>。這將避免內(nèi)部數(shù)組調(diào)整大小。

這是我所擁有的:

class Program

{

    static void Main(string[] args)

    {

        // warming up

        CreateNumbersYield(1);

        CreateNumbersList(1, true);

        Measure(null, () => { });


        // testing

        var size = 1000000;


        Measure("Yield", () => CreateNumbersYield(size));

        Measure("Yield + ToList", () => CreateNumbersYield(size).ToList());

        Measure("List", () => CreateNumbersList(size, false));

        Measure("List + Set initial capacity", () => CreateNumbersList(size, true));


        Console.ReadLine();

    }


    static void Measure(string testName, Action action)

    {

        var sw = new Stopwatch();


        sw.Start();

        action();

        sw.Stop();


        Console.WriteLine($"{testName} completed in {sw.Elapsed}");

    }


    static IEnumerable<int> CreateNumbersYield(int size) //for yield

    {

        for (int i = 0; i < size; i++)

        {

            yield return i;

        }

    }


    static IEnumerable<int> CreateNumbersList(int size, bool setInitialCapacity) //for list

    {

        var list = setInitialCapacity ? new List<int>(size) : new List<int>();


        for (int i = 0; i < size; i++)

        {

            list.Add(i);

        }


        return list;

    }

}

結(jié)果(發(fā)布版本):


Yield completed in 00:00:00.0001683

Yield + ToList completed in 00:00:00.0121015

List completed in 00:00:00.0060071

List + Set initial capacity completed in 00:00:00.0033668

如果我們比較可比較的情況(Yield + ToList& List + Set initial capacity),yield速度要慢得多。


查看完整回答
反對 回復(fù) 2022-06-18
  • 2 回答
  • 0 關(guān)注
  • 123 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號