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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

C#如何yield返回SelectMany?

C#如何yield返回SelectMany?

C#
翻過高山走不出你 2023-09-24 15:57:55
假設(shè)我有以下通用組合生成器靜態(tài)方法:public static IEnumerable<IEnumerable<T>> GetAllPossibleCombos<T>(    IEnumerable<IEnumerable<T>> items){    IEnumerable<IEnumerable<T>> combos = new[] {new T[0]};    foreach (var inner in items)        combos = combos.SelectMany(c => inner, (c, i) => c.Append(i));     return combos;}也許我沒有正確理解這一點(diǎn),但這不是在 RAM 中構(gòu)建整個(gè)組合列表嗎?如果有大量項(xiàng)目,該方法可能會(huì)導(dǎo)致計(jì)算機(jī)內(nèi)存不足。有沒有辦法重寫方法以yield return在每個(gè)組合上使用 a ,而不是返回整個(gè)組合集?
查看完整描述

2 回答

?
楊魅力

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超6個(gè)贊

你的問題中有一些誤解,這很棒,因?yàn)楝F(xiàn)在你有機(jī)會(huì)了解事實(shí)而不是神話。


首先,您正在實(shí)現(xiàn)的方法通常稱為CartesianProduct,而不是GetAllPossibleCombos,因此請(qǐng)考慮重命名它。


也許我沒有正確理解這一點(diǎn)

你沒有正確理解它。

這不是在 RAM 中構(gòu)建整個(gè)組合列表嗎?

不。?查詢構(gòu)建器構(gòu)建查詢,而不是執(zhí)行查詢的結(jié)果。?當(dāng)你執(zhí)行 a 時(shí)SelectMany,你得到的是一個(gè)將在將來(lái)進(jìn)行選擇的對(duì)象。您不會(huì)得到該選擇的結(jié)果。

如果有大量項(xiàng)目,該方法可能會(huì)導(dǎo)致計(jì)算機(jī)內(nèi)存不足。

今天是停止將內(nèi)存和 RAM 視為同一事物的好日子。當(dāng)進(jìn)程耗盡內(nèi)存時(shí),它不會(huì)耗盡 RAM。它耗盡了地址空間(不是 RAM)??紤]內(nèi)存的更好方法是:內(nèi)存是磁盤上的頁(yè)面文件,而 RAM 是特殊的硬件,可以使頁(yè)面文件更快。當(dāng) RAM 耗盡時(shí),計(jì)算機(jī)的運(yùn)行速度可能會(huì)慢得令人無(wú)法接受,但在地址空間耗盡之前,內(nèi)存不會(huì)耗盡。請(qǐng)記住,進(jìn)程內(nèi)存是虛擬化的

現(xiàn)在,可能存在執(zhí)行此代碼效率低下的情況,因?yàn)槊杜e查詢耗盡了堆棧。在某些情況下,執(zhí)行可能會(huì)變得低效,因?yàn)槟鷮?n 個(gè)項(xiàng)目向上移動(dòng)到堆棧 n 深。我建議您對(duì)代碼進(jìn)行更深入的分析,看看是否是這種情況,然后進(jìn)行報(bào)告。


有沒有辦法重寫方法以在每個(gè)組合上使用收益返回,而不是返回整個(gè)組合集?

SelectMany是作為循環(huán)yield return中的a 實(shí)現(xiàn)的foreach,因此您已經(jīng)yield return在每個(gè)組合上將其實(shí)現(xiàn)為 a ;你剛剛隱藏了yield return對(duì) 的調(diào)用SelectMany。

也就是說(shuō),SelectMany<A, B, C>(IE<A> items, Func<A, IE<B>> f, Func<A, B, C> g)實(shí)現(xiàn)如下:

foreach(A?a?in?items)
??foreach(B?b?in?f(a))
??????yield?return?g(a,?b);

所以你已經(jīng)在 中完成了yield return。

如果你想編寫一個(gè)直接執(zhí)行 a的方法yield return,那就有點(diǎn)困難了;最簡(jiǎn)單的方法是在每個(gè)子序列上形成一個(gè)枚舉器數(shù)組,然后從每個(gè)Current枚舉器創(chuàng)建一個(gè)向量,yield return即向量,然后將正確的迭代器前進(jìn)一步。繼續(xù)這樣做,直到不再有正確的迭代器可以前進(jìn)。

正如您可能從描述中看出的那樣,簿記變得混亂。這是可行的,但編寫起來(lái)并不是很令人愉快的代碼。不過不妨嘗試一下!該解決方案的好處是,您可以保證獲得良好的性能,因?yàn)槟幌娜魏味褩!?/p>

查看完整回答
反對(duì) 回復(fù) 2023-09-24
?
繁花不似錦

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超4個(gè)贊

SelectMany和其他 Linq 方法返回一個(gè)IEnumerable,僅在枚舉集合時(shí)才延遲計(jì)算。ToList()這可以采用orToArray()調(diào)用或在循環(huán)中對(duì)其進(jìn)行迭代的形式foreach。當(dāng)您在調(diào)試器中看到消息警告擴(kuò)展集合將枚舉可枚舉對(duì)象時(shí),這就是它警告您的行為。該集合尚未枚舉 - Linq 查詢僅構(gòu)建一個(gè)調(diào)用鏈,告訴它如何枚舉數(shù)據(jù)。


因此,您對(duì) RAM 使用情況的擔(dān)憂不一定準(zhǔn)確(取決于啟動(dòng)的具體類型IEnumerable)。即使您調(diào)用ToList()orToArray()并將對(duì)該集合的引用存儲(chǔ)在變量中,如果集合元素是引用類型,那么它也不會(huì)是副本。


在您的示例中,yield return如果您想延遲構(gòu)建元素集合而不將其存儲(chǔ)在單獨(dú)的集合中(例如返回列表或數(shù)組,這需要額外的復(fù)制),則可以為您提供方便。我認(rèn)為它不適用于您想要做的事情,因?yàn)镾electMany已經(jīng)有這種行為。


如果您想嘗試一下,Linq 可以輕松生成大型列表Enumerable.Repeat


// Define a collection with 10000000 items (items not created yet)

var manyItems = Enumerable.Repeat(123, 10000000);


// Enumerate the enumerable via ToList: creates the int 10000000 times

var manyItemsConcrete = manyItems.ToList();


// same deal with reference types

var manyReferenceTypes = Enumerable.Repeate(new object(), 10000000);

var manyReferenceTypesConcrete = manyReferenceTypes.ToList();


// This list already exists in RAM taking up space

var list = new List<object> { new object(), new object() /* ... x10000000 */ }

// This defines a transform on list, but doesn't take up RAM

var enumerable = list.Select(x => x.ToString());


// Now, there are two lists taking up RAM

var newList = enumerable.ToList();


查看完整回答
反對(duì) 回復(fù) 2023-09-24
  • 2 回答
  • 0 關(guān)注
  • 146 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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