当前位置: 首页 > Web前端 > JavaScript

NgRxSelector的Memoization特性学习笔记

时间:2023-03-27 17:43:08 JavaScript

在计算机编程领域,memoization或memoisation是一种优化技术,主要用于通过存储昂贵函数调用的结果并在再次出现相同输入时返回缓存的结果来加速计算机程序。记忆化也被用于其他情况(并且用于速度提升以外的目的),例如简单的相互递归下降解析。尽管与缓存相关,但记忆化是指此优化的特定情况,将其与缓存或页面替换等缓存形式区分开来。在某些逻辑编程语言的上下文中,记忆也称为表格。记忆功能“记住”对应于某些特定输入集的结果。使用记住的输入的后续调用返回记住的结果而不是重新计算它,从而消除了使用给定参数调用的主要成本,除了第一次使用这些参数调用函数。记住的关联集可以是替换算法控制的固定大小集,也可以是固定集,这取决于函数的性质及其目的。一个函数只有在引用透明的情况下才能被记忆;也就是说,仅当调用该函数与用其返回值替换函数调用具有完全相同的效果时。(但是,此限制有一个特殊情况例外。)虽然与查找表相关,但由于内存在其实现中经常使用此类表,因此内存会根据需要即时填充其结果缓存,而不是提前。Memoization是一种以牺牲空间为代价来降低函数时间成本的优化方法;也就是说,记忆函数以更高的计算机内存空间使用率为代价优化了速度。算法的时间/空间“成本”在计算中有一个特定的名称:计算复杂性。所有函数在时间(即它们需要时间来执行)和空间上都具有计算复杂性。什么是NgRx选择器选择器是用于获取存储状态切片的纯函数。@ngrx/store提供了一些帮助函数来优化这个选择。Selector也符合singleresponsibility和Singleresponsibility,一个selector只接触一个fragment的State。使用createSelector和createFeatureSelector函数时,@ngrx/store会跟踪调用选择器函数的最新参数。因为选择器是纯函数,所以当参数匹配时可以返回最后的结果而无需重新调用选择器函数。这可以提供性能优势,特别是对于执行昂贵计算的选择器。这种做法称为记忆。也就是说,虽然我们实现了Selector,但是这些selector在运行时可能只会执行一次,因为如果输入参数相同,NgRx框架会使用缓存的结果直接返回给调用者,而不需要重复调??用我们的Selector.示例:为一个状态使用选择器import{createSelector}from'@ngrx/store';exportinterfaceFeatureState{counter:number;}exportinterfaceAppState{feature:FeatureState;}exportconstselectFeature=(state:AppState)=>状态。特征;导出常量selectFeatureCount=createSelector(selectFeature,(state:FeatureState)=>state.counter);console.log('ok');示例:对多片状态使用选择器createSelector可以使用基于相同状态(State)的多个片从状态中选择一些数据。createSelector函数最多可以使用8个选择器函数来进行更完整的状态选择。例如,假设您所在的州有一个selectedUser对象。您还有一个allBooks书籍对象数组。并且您想显示当前用户的所有书籍。您可以使用createSelector来实现这一点。您的可见书籍将始终是最新的,即使您在allBooks中更新它们也是如此。如果选择了一个,他们将始终显示属于您的用户的书籍,如果没有选择用户,他们将显示所有书籍。纯函数在CreateSelector中传递。从'@ngrx/store'导入{createSelector};导出界面用户{id:数字;name:string;}exportinterfaceBook{id:number;userId:编号;名称:字符串;}导出接口AppState{selectedUser:用户;allBooks:Book[];}exportconstselectUser=(state:AppState)=>state.selectedUser;exportconstselectAllBooks=(state:AppState)=>state.allBooks;exportconstselectVisibleBooks=createSelector(selectUser,selectAllBooks,(selectedUser:User,allBooks:Book[])=>{if(selectedUser&&allBooks){returnallBooks.filter((book:Book)=>book.userId===selectedUser.id);}else{returnallBooks;}});SelectingFeatureStatescreateFeatureSelector是一种返回顶级特征状态的便捷方法。它返回状态特征切片的类型化选择器函数。导入{createSelector,createFeatureSelector}from'@ngrx/store';exportconstfeatureKey='feature';exportinterfaceFeatureState{counter:number;}exportinterfaceAppState{feature:FeatureState;}exportconstselectFeature=createFeatureSelector(featureKey);exportconstselectFeatureCount=createSelector(selectFeature,(state:FeatureState)=>state.counter);ResettingMemoizedSelectors调用createSelector或createFeatureSelector返回的selector函数内存初始值为null。选择器第一次被调用后,它的记忆值被存储在内存中。如果随后使用相同的参数调用选择器,它将返回记住的值。如果随后使用不同的参数调用选择器,它将重新计算并更新其记忆值。一个例子:import{createSelector}from'@ngrx/store';导出接口状态{counter1:number;counter2:数字;}exportconstselectCounter1=(state:State)=>state.counter1;导出常量selectCounter2=(state:State)=>state.counter2;exportconstselectTotal=createSelector(selectCounter1,selectCounter2,(counter1,counter2)=>counter1+counter2);//selectTotal的记忆值为null,因为它尚未被调用。letstate={counter1:3,counter2:4};selectTotal(state);//计算3和4的总和,返回7。selectTotal现在有一个记忆值7selectTotal(state);//不计算3和4的总和。selectTotal而是返回7state={...state,counter2:5};selectTotal(state);的记忆值//计算3和5的总和,返回8。selectTotal现在有一个memoized值8select寄存器的内存值无限期地保留在内存中。例如,如果记住的值是不再需要的大数据集,则可以将记住的值重置为空,以便从内存中删除大数据集。这可以通过调用选择器上的release方法来完成。选择总计(状态);//返回8selectTotal.release()的记忆值;//selectTotal的记忆值现在为空