d可替代hasUDA吗
在项目中,我大量使用hasUDA,getUDAs和getSymbolsByUDA
.dmd
需要大约3.2Gb
来编译它,一个dub
重新编译需要大约8-14
秒.
如下内容,与环境无关:
static if (isSerialisable!member)
{
import std.path : buildNormalizedPath;
static if (hasUDA!(this.tupleof[i], Resource))
{
member = buildNormalizedPath(state.settings.resourceDirectory, member);
}
else static if (hasUDA!(this.tupleof[i], Configuration))
{
member = buildNormalizedPath(state.settings.configDirectory, member);
}
}
private alias allEventHandlerFunctionsInModule =
Filter!(isSomeFunction, getSymbolsByUDA!(thisModule, IRCEventHandler));
enum isSetupFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.setup);
enum isEarlyFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.early);
enum isLateFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.late);
enum isCleanupFun(alias T) = (getUDAs!(T, IRCEventHandler)[0]._when == Timing.cleanup);
alias hasSpecialTiming = templateOr!(isSetupFun, isEarlyFun, isLateFun, isCleanupFun);
alias isNormalEventHandler = templateNot!hasSpecialTiming;
alias setupFuns = Filter!(isSetupFun, this.allEventHandlerFunctionsInModule);
alias earlyFuns = Filter!(isEarlyFun, this.allEventHandlerFunctionsInModule);
alias lateFuns = Filter!(isLateFun, this.allEventHandlerFunctionsInModule);
alias cleanupFuns = Filter!(isCleanupFun, this.allEventHandlerFunctionsInModule);
alias pluginFuns = Filter!(isNormalEventHandler, this.allEventHandlerFunctionsInModule);
如果hasUDA
等很差,可用什么来代替?
我需要它们
在编译时工作.只需要求值hasUDA
为true
或false
,但对getUDAs
及getSymbolsByUDA
,我需要它们按符号(而不是符号的串名)
解析.
我还有别的选择吗?
因此,有个排除
关键字将是很好的.但现在,有个更好
的方法.在LDC
中,构建我整个引擎
需要250mb
,在DMD
中,我没有检查,但也差不多.
这里说,使用udaIndex
比使用hasUDA
和getUDA
更好.
getUDA
可简单地更改为:
__traits(getAttributes, yourMemberHere)
许多std.traits
实际用,用静如(static if)+别名序列(AliasSeq)
的Filter!()
递归模板.递归模板超重
,很慢
.
在标准库
中最好避免递归
类型,特别是经常使用时.
那么,如果想构造更好过滤
,该怎么做呢?好吧,构造一个索引数组
来代替AliasSeq
.如果不使用递归模板
,就不可能程序化
构造AliasSeq
.这样就可迭代
这些索引
了.
需要更多手工
操作,但长期运行
时效果更好
,特别是不想改变反射
函数时.
因此,避免过滤
,这似乎是主要瓶颈
.特别是经常迭代
所有成员.最好用单次迭代及使用相同数据.
代码类似如下:
alias setupFuns = Filter!(isSetupFun, this.allEventHandlerFunctionsInModule);
alias earlyFuns = Filter!(isEarlyFun, this.allEventHandlerFunctionsInModule);
///伪码扩展表示
template setupFuns alias pred)
{
alias Filter = AliasSeq!();
static foreach (member; Module)
static if (pred!arg)
Filter = AliasSeq!(Filter, arg);
}
template earlyFuns(alias pred)
{
alias Filter = AliasSeq!();
static foreach (member; Module)
static if (pred!arg)
Filter = AliasSeq!(Filter, arg);
}
更好解决办法是:
static foreach(mem; __traits(allMembers, thisModule))
{
static if(is(typeof(__traits(getMember, thisModule, mem)) == EarlyFunc))
else static if(is(typeof(__traits(getMember, thisModule, mem)) == LateFunc))
}
这样,避免了多次递归模板
,只使用一次反射
(迭代一次
与迭代n次
区别).
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现