热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

使用宏避免输入Julia

如何解决《使用宏避免输入Julia》经验,为你挑选了1个好方法。

我已经读过Julia拥有Macros,但是我不确定Julia提供的Macros是否是我正在考虑的宏。

我有以下表达:

Global.data[
  Dates.value(Dates.Year(dtCursor)) - 2000, 
  Dates.value(Dates.Month(dtCursor)), 
  Dates.value(Dates.Day(dtCursor)),
  Dates.value(Dates.Hour(dtCursor)) + 1, 
  Dates.value(Dates.Minute(dtCursor)) + 1, 
  1
]

我会重复很多次。我想知道是否可以使用dtCursor作为参数的宏(在其他情况下可能是其他变量)为我键入所有内容。因此,我正在寻找通常在宏汇编程序中找到的宏扩展功能。

我绝对不想将此作为函数包含在内,因为此代码已执行了成千上万次,因此,我不想增加函数调用的开销。

我试过了:

macro readData(_dtCursor, value)
  return :(
    Global.data[
      Dates.value(Dates.Year(_dtCursor)) - 2000, 
      Dates.value(Dates.Month(_dtCursor)), 
      Dates.value(Dates.Day(_dtCursor)),
      Dates.value(Dates.Hour(_dtCursor)) + 1, 
      Dates.value(Dates.Minute(_dtCursor)) + 1, 
      value
    ]
  )
end

后来被调用:

println(@readData(dtCursor, 1))

dtCursorDateTime变量在哪里。

但我得到:

ERROR: LoadError: UndefVarError: _dtCursor not defined

我已经阅读了https://docs.julialang.org/en/v1/manual/metaprogramming/index.html#man-macros-1,但是真的很乐于帮助您理解这种情况下的处理方法。



1> Lyndon White..:
使用功能

我绝对不想将此作为函数包含在内,因为此代码已执行了成千上万次,因此,我不想增加函数调用的开销。

肯定是错的。
您可能在某些语言中是正确的,但在JuliaLang中却不正确。
(我确实认为这是一个非常有用的问题,因为可以突出显示其他人不要这样做)

该函数调用是内联的,即使没有,我们@inline在使用宏之前也想使用其他工具()。

宏用于语法转换。
如果您不进行语法转换,请在使用宏之前再考虑一下。

这是史蒂文·约翰逊(Steven G. Johnson)在juliacon上的主题演讲中提到的一个好观点的链接:“功能对于杰夫·贝赞森(Jeff Bezanson)来说已经足够好。不要试图超越杰夫·比扎森(Jeff Bezason)”

如何将其编写为宏和函数

以下回答您的原始问题

using Dates
using BenchmarkTools


macro readData(_dtCursor, value)
  return :(
    Global.data[
      Dates.value(Dates.Year($(esc(_dtCursor)))) - 2000, 
      Dates.value(Dates.Month($(esc(_dtCursor)))), 
      Dates.value(Dates.Day($(esc(_dtCursor)))),
      Dates.value(Dates.Hour($(esc(_dtCursor)))) + 1, 
      Dates.value(Dates.Minute($(esc(_dtCursor)))) + 1, 
      $value
    ]
  )
end


function readData(_dtCursor, value)
    Global.data[
      Dates.value(Dates.Year(_dtCursor)) - 2000, 
      Dates.value(Dates.Month(_dtCursor)), 
      Dates.value(Dates.Day(_dtCursor)),
      Dates.value(Dates.Hour(_dtCursor)) + 1, 
      Dates.value(Dates.Minute(_dtCursor)) + 1, 
      value
    ]
end

进行基准测试。

您说这将运行10,000次。因此,为了安全起见,我将以100_000次使用为基准。

const Global = (; data=[join((y, m, d, h, M, s)," ") for y in 2000:2010, m in 1:3, d in 1:20, h in 1:10, M in 1:30, s in 1:30]);
size(Global.data)
length(Global.data)

const sample_dts = map(1:100_000) do _
   y, m, d, h, M, s = rand.(axes(Global.data))
   dt = DateTime(y+2000, m, d, h-1, M-1)
end;


func_demo() = [readData(dt, 3) for dt in sample_dts];
macro_demo() = [@readData(dt, 3) for dt in sample_dts];


@btime func_demo()
@btime macro_demo()

他们基准相同

julia> @btime macro_demo();
  5.409 ms (3 allocations: 781.34 KiB)

julia> @btime func_demo();
  5.393 ms (3 allocations: 781.34 KiB)

实际上,它们专门用于(基本上)相同的代码。

julia> @code_typed macro_demo()
CodeInfo(
1 ? %1 = Main.sample_dts::Core.Compiler.Const(DateTime[2002-01-18T04:19:00, 2001-01-19T08:22:00, 2006-02-08T04:07:00, 2011-01-08T09:03:00, 2006-02-10T06:18:00, 2002-03-12T00:05:00, 2011-02-20T08:29:00, 2011-02-20T07:12:00, 2005-01-13T03:22:00, 2006-01-01T00:29:00  …
  2005-03-10T04:29:00, 2002-03-12T09:11:00, 2002-03-11T00:28:00, 2007-02-12T02:26:00, 2003-02-15T07:29:00, 2009-01-01T02:02:00, 2009-
01-03T02:11:00, 2001-02-16T03:16:00, 2004-01-17T05:12:00, 2010-02-02T05:10:00], false)
?   %2 = %new(Base.Generator{Array{DateTime,1},getfield(Main, Symbol("##50#51"))}, getfield(Main, Symbol("##50#51"))(), %1)::Base.Gen
erator{Array{DateTime,1},getfield(Main, Symbol("##50#51"))}
?   %3 = invoke Base.collect(%2::Base.Generator{Array{DateTime,1},getfield(Main, Symbol("##50#51"))})::Array{String,1}
???      return %3
) => Array{String,1}


julia> @code_typed getfield(Main, Symbol("##50#51")).instance(1)  # check the internals
?   %1 = %1 = Main.Global::Core.Compiler.Const((#==GIANT Inlined COnst==#)
?   %2 = Base.getfield(%1, :data)::Array{String,6}
?   %3 = Base.sub_int(dt, 2000)::Int64
?   %4 = Base.add_int(dt, 1)::Int64
?   %5 = Base.add_int(dt, 1)::Int64
?   %6 = Base.arrayref(true, %2, %3, dt, dt, %4, %5, 3)::String
???      return %6
) => String



julia> @code_typed func_demo()
CodeInfo(
1 ? %1 = Main.sample_dts::Core.Compiler.Const(DateTime[2002-01-18T04:19:00, 2001-01-19T08:22:00, 2006-02-08T04:07:00, 2011-01-08T09:03:00, 2006-02-10T06:18:00, 2002-03-12T00:05:00, 2011-02-20T08:29:00, 2011-02-20T07:12:00, 2005-01-13T03:22:00, 2006-01-01T00:29:00  …  2005-03-10T04:29:00, 2002-03-12T09:11:00, 2002-03-11T00:28:00, 2007-02-12T02:26:00, 2003-02-15T07:29:00, 2009-01-01T02:02:00, 2009-
01-03T02:11:00, 2001-02-16T03:16:00, 2004-01-17T05:12:00, 2010-02-02T05:10:00], false)
?   %2 = %new(Base.Generator{Array{DateTime,1},getfield(Main, Symbol("##43#44"))}, getfield(Main, Symbol("##43#44"))(), %1)::Base.Gen
erator{Array{DateTime,1},getfield(Main, Symbol("##43#44"))}
?   %3 = invoke Base.collect(%2::Base.Generator{Array{DateTime,1},getfield(Main, Symbol("##43#44"))})::Array{String,1}
???      return %3
) => Array{String,1}

julia> @code_typed getfield(Main, Symbol("##43#44")).instance(1)
CodeInfo(
1 ? %1 = Main.Global::NamedTuple{(:data,),Tuple{Array{String,6}}}
?   %2 = Base.getfield(%1, :data)::Array{String,6}
?   %3 = Base.sub_int(dt, 2000)::Int64
?   %4 = Base.add_int(dt, 1)::Int64
?   %5 = Base.add_int(dt, 1)::Int64
?   %6 = Base.arrayref(true, %2, %3, dt, dt, %4, %5, 3)::String
???      return %6
) => String

两者之间的生成器功能之间存在很小的差异。当内联时,值变为a Compliler.Const或a NamedTuple,但是之后LLVM的差异也是如此(我认为(检查@code_llvm您是否真的很感兴趣。但是我们已经对杂草非常了解了。)

首先,这可能是要优化的错误代码。

长期指导您进行任何优化的基准测试。还应该分析代码以确定哪些值得优化。该函数仅被调用10,000次,并且不分配巨型数组等,可能不值得过多担心。特别是如果您只担心函数调用开销,这仅是少数几个CPU周期。


推荐阅读
  • 本文探讨了互联网服务提供商(ISP)如何可能篡改或插入用户请求的数据流,并提供了有效的技术手段来防止此类劫持行为,确保网络环境的安全与纯净。 ... [详细]
  • JavaScript 跨域解决方案详解
    本文详细介绍了JavaScript在不同域之间进行数据传输或通信的技术,包括使用JSONP、修改document.domain、利用window.name以及HTML5的postMessage方法等跨域解决方案。 ... [详细]
  • 搭建个人博客:WordPress安装详解
    计划建立个人博客来分享生活与工作的见解和经验,选择WordPress是因为它专为博客设计,功能强大且易于使用。 ... [详细]
  • 【MySQL】frm文件解析
    官网说明:http:dev.mysql.comdocinternalsenfrm-file-format.htmlfrm是MySQL表结构定义文件,通常frm文件是不会损坏的,但是如果 ... [详细]
  • 本文详细介绍了 Node.js 中 OS 模块的 arch 方法,包括其功能、语法、参数以及返回值,并提供了具体的使用示例。 ... [详细]
  • 本文详细介绍了五种常用的PHP排序算法——冒泡排序、选择排序、插入排序、希尔排序和堆排序。每种算法都附有代码示例,并通过打印和延时操作来直观展示排序过程。欢迎指出任何错误。 ... [详细]
  • 数据输入验证与控件绑定方法
    本文提供了多种数据输入验证函数及控件绑定方法的实现代码,包括电话号码、数字、传真、邮政编码、电子邮件和网址的验证,以及报表绑定和自动编号等功能。 ... [详细]
  • 美团安全响应中心推出全新配送业务测试活动,带来双重福利,邀您共同参与! ... [详细]
  • 随着Linux操作系统的广泛使用,确保用户账户及系统安全变得尤为重要。用户密码的复杂性直接关系到系统的整体安全性。本文将详细介绍如何在CentOS服务器上自定义密码规则,以增强系统的安全性。 ... [详细]
  • 本文详细介绍如何安装和配置DedeCMS的移动端站点,包括新版本安装、老版本升级、模板适配以及必要的代码修改,以确保移动站点的正常运行。 ... [详细]
  • 探讨了在HTML表单中使用元素代替进行表单提交的方法。 ... [详细]
  • 吴石访谈:腾讯安全科恩实验室如何引领物联网安全研究
    腾讯安全科恩实验室曾两次成功破解特斯拉自动驾驶系统,并远程控制汽车,展示了其在汽车安全领域的强大实力。近日,该实验室负责人吴石接受了InfoQ的专访,详细介绍了团队未来的重点方向——物联网安全。 ... [详细]
  • 利用Node.js实现PSD文件的高效切图
    本文介绍了如何通过Node.js及其psd2json模块,快速实现PSD文件的自动化切图过程,以适应项目中频繁的界面更新需求。此方法不仅提高了工作效率,还简化了从设计稿到实际应用的转换流程。 ... [详细]
  • 本文详细介绍了如何在最新版本的Xcode中重命名iOS项目,包括项目名称、应用名称及相关的文件夹和配置文件。通过本文,开发者可以轻松完成项目的重命名工作。 ... [详细]
  • 本文详细介绍了如何在Oracle数据库中使用SQL进行分页查询,通过嵌套查询和ROWNUM函数的应用,实现数据的高效分页展示。 ... [详细]
author-avatar
guitar402
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有