multithreading - 我应该如何使解析器并发?

标签 multithreading clojure concurrent-programming reference-type

我正在努力在Clojure中实现音乐编程语言解析器。这个想法是您使用文本文件作为命令行参数来运行解析器程序。文本文件包含我正在开发的这种音乐语言的代码;解析器解释代码并找出已经声明了哪些“乐器实例”,并且对于每个乐器实例,它解析代码并返回乐器所执行的一系列音乐“事件”(音符,和弦,休止符等)。 。因此,在最后一步之前,我们有多个“音乐代码”字符串,每个乐器实例一个字符串。

我对Clojure还是有些陌生,但仍在学习如何使用引用类型和线程/并发的细微差别。我的解析器将要进行一些复杂的解析,所以我认为使用并发来提高性能将使它受益。这是我的问题:

  • 看来,最简单的方法是在通过初始解析(单线程操作)“拆分”工具后保存并发,然后在同一线程的不同线程上解析每个工具的代码时间(而不是等待每个乐器完成解析再移到下一个乐器)。我是在正确的轨道上吗,还是有一种更有效和/或合乎逻辑的方式来构建我的“并发计划”?
  • 从性能或代码维护的角度来看,我有什么选项可用于实现此并发解析,以及哪一个可能效果最好?看起来好像很简单:(map #(future (process-music-code %)) instrument-instances),但是我不确定是否有更好的方法来实现它,例如使用代理,通过Java interop进行手动线程或执行什么操作。我是并发编程的新手,所以以不同方式进行此操作的任何输入都很好。
  • 从我所读的内容中,似乎Clojure的引用类型在并发编程中起着重要的作用,我可以理解为什么,但是在处理多个线程时总是需要使用它们吗?我应该担心使某些数据可变吗?如果是这样的话,我正在编写的解析器的代码中应该特别可变的是什么?哪种引用类型最适合我在做什么?我的程序工作方式的本质(用户使用文本文件作为参数来运行程序-程序对其进行处理并将其转换为音频)使我似乎不需要任何可变的东西,因为输入数据永远都不会改变,所以我的直觉告诉我,我不需要使用任何引用类型,但是再说一遍,我可能无法完全理解Clojure中引用类型与并发之间的关系。
  • 最佳答案

    我建议您通过过早的优化来分散自己对更重要的事情的注意力(例如弄清楚音乐语言的细节)。最好先编写最简单,最容易编写代码的解析器,以启动并运行它。如果发现它太慢,则可以查看如何优化以获得更好的性能。

    解析器应该是完全独立的,并且无论如何可能不会花费很多代码,因此即使您以后将它扔掉并重写它,也不会造成很大的损失。如果编写第二个解析器,那么编写第一个解析器的经验将有所帮助。

    其他要点:

    您对引用类型绝对正确-您可能不需要任何引用类型。您的程序是一个编译器-它接受输入,对其进行转换,写入输出然后退出。这是纯函数式编程的理想情况,没有任何可变的东西,所有数据流都完全通过函数参数和返回值进行。

    通常,使用解析器生成器是获得有效解析器的最快方法,但是我还没有找到Clojure真正好的解析器生成器。 Parsley有一个非常不错的API,但是它会生成LR(0)解析器,该解析器对于每个“节”的开头/结尾没有清晰,明确的标记的东西几乎是无用的。 (就像S表达式使用parens打开和关闭的方式一样。)那里有几个parser组合器库,例如squarepeg,但是我不喜欢它们的API,而是更喜欢使用以下代码编写自己的手动编码的递归下降解析器:我自己的解析器组合器之类的实现。 (它们的速度并不快,但是代码读起来确实不错。)

    关于multithreading - 我应该如何使解析器并发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21148671/

    相关文章:

    Java 阻塞问题 : Why would JVM block threads in many different classes/methods?

    iOS线程违规检测?

    c++ - C++中的线程间通信

    java - 向简单的 java 游戏添加开始、停止、重置按钮

    python - 在 Flask 中返回立即响应,但在新线程中完成处理

    clojure - 有没有办法在 leinegen 中设置系统属性?

    clojure - 如何为lein run和lein repl都定义project.clj?

    c# - 收集拥有对象时如何终止工作线程?

    java - 为什么 Clojure 中的嵌套循环/递归速度很慢?

    go - 所有的 goroutines 都睡着了——死锁! - - - - 错误