In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article focuses on "what is java memory and functional collaboration". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "what is java memory and functional collaboration"?
Memory
The term memory was coined by Donald Michie, a British artificial intelligence researcher, to represent a function-level cache of repeating values. Nowadays, memory is common in functional programming languages, either as a built-in feature or as a feature that is relatively easy to implement.
Memory is helpful in the following scenarios. Suppose you have to call a performance-focused function repeatedly. A common solution is to build an internal cache. Each time you calculate the value of a parameter set, you put the value in the cache as a clue to the parameter value. In the future, if the function is called with previous arguments, it will return the value from the cache instead of recalculating it. Function caching is a classic computer science tradeoff: it uses more memory (we often have plenty of memory) to continuously achieve higher performance.
The function must be pure for caching technology to work. A pure function is a function with no side effects: it does not reference any other mutable class fields, does not set any value other than the return value, and relies only on parameters as input. All the methods in the java.lang.Math class are good examples of pure functions. Obviously, you can successfully reuse cached results only if the function reliably returns the same value for a given set of parameters.
Memory in Groovy
Memory is simple in Groovy, and Groovy contains a series of memoize () functions on the Closure class. For example, suppose you have an expensive hashing algorithm so that you need to cache the results to improve efficiency. To do this, you can use the closure block syntax to define the method and call the memoize () function on return, as shown in listing 1. I'm not suggesting that the performance of the ROT13 algorithm used in listing 1 (that is, a version of the Caesar cipher) is challenged, but it's important to assume that the cache exists in this example.
Listing 1. Memory in Groovy
Class NameHash {def static hash = {name-> name.collect {rot13 (it)} .join ()} .memoize () public static char rot13 (s) {char c = sswitch (c) {case 'A'..'M':case 'asides.. return c + 13case' N'..'Z':case 'n certificates: return c-13default: return c}} class NameHashTest extends GroovyTestCase {void testHash () {assertEquals ("ubzre", NameHash.hash.call ("homer"))}}
Normally, the Groovy function definition looks like rot13 () in listing 1, with the method body after the parameter list. The hash () function definition uses a slightly different syntax, assigning code blocks to hash variables. The last part of the definition is a call to memoize (), which automatically creates an internal cache for duplicate values and ties to this parameter.
The memoize () method is actually a series of methods that give you some control over the cache characteristics, as shown in Table 1.
Table 1. Memoize () series of Groovy
Memoize () returns an instance of the closure containing cache memoizeAtMost () sets an upper limit for the number of cache elements memoizeAtLeast (int protectedCacheSize) sets a lower limit for the number of cache elements, protects a certain number of elements from garbage collection memoizeBetween (int protectedCacheSize, int maxCacheSize) sets a lower limit and an upper limit for the number of cache elements
The methods in Table 1 provide you with coarse-grained control over cache features, which is not a fine-grained way to tune cache features directly. Memory should be a general mechanism that you can use to easily optimize common caching situations.
Memory in Clojure
Memory built into Clojure. You can use the (memoize) function to internalize any function. For example, if you already have a (hash "homer") function, you can memorize it for a cached version through (memoize (hash "homer")). Listing 2 implements the name hash example in listing 1 in Clojure.
Listing 2. Clojure memory
(defn name-hash [name] (apply str (map # (rot13%) (split name # "\ d") (def name-hash-m (memoize name-hash)) (testing "name hash" (is (= "ubzre" (name-hash "homer") (testing "memoized name hash" (is (= "ubzre" (name-hash-m "homer"))
Note that in listing 1, calling the in-memory function requires a call to the call () method. In the Clojure version, the in-memory method calls are ostensibly identical, but add indirectness and caching that are invisible to the method user.
Memory in Scala
Scala does not implement memory directly, but there is a collection method called getOrElseUpdate () that handles most of the work of implementing it, as shown in listing 3.
Listing 3. Scala memory
Def memoize [A, B] (f: a = > B) = new (A = > B) {val cache = scala.collection.mutable.Map [A, B] () def apply (x: a): B = cache.getOrElseUpdate (x, f (x))} def nameHash = memoize (hash)
The getOrElseUpdate () function in listing 3 is the perfect operator for caching. It retrieves the matching value or creates a new entry when there is no matching value.
Combinatorial function characteristics
To combine by composition.
Composition has many meanings in software development. Function composition refers to the ability to combine functions to obtain compound results. In mathematical terms, if you have an f (x) function and a g (x) function, you should be able to execute f (g (x)). In software terminology, if you have an a () function that converts a string to uppercase and a b () function that removes excess spaces, the composite function performs both tasks.
In the previous section and previous Java next-generation articles, I introduced many details of functional programming, especially those related to the next-generation language of Java. However, the real power of functional programming lies in the combination of features and the way the solution is executed.
Object-oriented programmers tend to constantly create new data structures and accompanying operations. After all, building new classes and the messages passed between them are the main language patterns. But building so many custom structures makes it difficult to build reusable code at the lowest level. Functional programming languages refer to some core code structures and build optimization mechanisms to understand them.
The following is an example. Listing 4 shows the indexOfAny () method from the Apache Commons framework, which provides a number of helpers for Java programming.
Listing 4. IndexOfAny () from Apache Commons
/ / From Apache Commons Lang, http://commons.apache.org/lang/public static int indexOfAny (String str, char [] searchChars) {if (isEmpty (str) | | ArrayUtils.isEmpty (searchChars)) {return INDEX_NOT_FOUND;} int csLen = str.length (); int csLast = csLen-1 leading searchLen = searchChars.length;int searchLast = searchLen-1 for (int I = 0; I
< csLen; i++) {char ch = str.charAt(i);for (int j = 0; j < searchLen; j++) { if (searchChars[j] == ch) {if (i < csLast && j < searchLast && CharUtils.isHighSurrogate(ch)) {if (searchChars[j + 1] == str.charAt(i + 1)) {return i;}} else {return i;}}}}return INDEX_NOT_FOUND;} 清单 4 中 1/3 的代码负责边缘检查和实现嵌套迭代所需的变量的初始化。我将逐步将此代码转换为 Clojure。作为第一步,我将删除边角情形,如清单 5 所示。 清单 5. 删除边角情形 public static int indexOfAny(String str, char[] searchChars) {when(searchChars) {int csLen = str.length();int csLast = csLen - 1;int searchLen = searchChars.length;int searchLast = searchLen - 1;for (int i = 0; i < csLen; i++) {char ch = str.charAt(i);for (int j = 0; j < searchLen; j++) {if (searchChars[j] == ch) {if (i < csLast && j < searchLast && CharUtils.isHighSurrogate(ch)) {if (searchChars[j + 1] == str.charAt(i + 1)) {return i;}} else {return i;}}}}return INDEX_NOT_FOUND;}} Clojure 会智能地处理 null 和 empty 情形,拥有 (when ...) 等智能函数,该函数仅在字符存在时返回 true。Clojure 具有动态(且强)类型,消除了在使用前声明变量类型的需求。因此,我可以删除类型声明,获得清单 6 中所示的代码。 清单 6. 删除类型声明 indexOfAny(str, searchChars) {when(searchChars) {csLen = str.length();csLast = csLen - 1;searchLen = searchChars.length;searchLast = searchLen - 1;for (i = 0; i < csLen; i++) {ch = str.charAt(i);for (j = 0; j < searchLen; j++) {if (searchChars[j] == ch) { if (i < csLast && j < searchLast && CharUtils.isHighSurrogate(ch)) {if (searchChars[j + 1] == str.charAt(i + 1)) {return i;}} else {return i;}}}}return INDEX_NOT_FOUND;}} for 循环 (命令式语言的主要元素)允许依次访问每个元素。函数式语言倾向于更多地依靠集合方法,这些方法已理解(或避免)了边角情形,所以我可删除 isHighSurrogate()(它检查字符编码)等方法和索引指针的操作。此转换的结果如清单 7 所示。 清单 7. 一个用于替换最里面的 for 的 when 子句 // when clause for innermost forindexOfAny(str, searchChars) {when(searchChars) {csLen = str.length(); for (i = 0; i < csLen; i++) { ch = str.charAt(i);when (searchChars(ch)) i;}}} 在清单 7 中,我将代码折叠到一个方法中,该方法会检查受欢迎的字符是否存在,在找到这些字符时,它会返回其索引。尽管我既未使用 Java 也未使用 Clojure,而是提供了一段陌生的伪代码,但这个 when 方法并不总是存在。但 Clojure 中还有 (when ) 方法,此代码会慢慢变成该方法。 接下来,我将最顶层的 for 循环替换为一种更加简洁的代码,使用 for comprehension: 一个结合了集合的访问和过滤(等)的宏。演变后的代码如清单 8 所示。 清单 8. 添加一个 comprehension // add comprehensionindexOfAny(str, searchChars) {when(searchChars) {for ([i, ch] in indexed(str)) { when (searchChars(ch)) i;}}} 要理解清单 8 中的 for comprehension,首先您必须理解一些部件。Clojure 中的 (indexed ...) 函数接受一个 Sequence 并返回一个包含编号的元素的序列。例如,如果我调用 (indexed '(a b c)),返回值为 ([0 a] [1 b] [2 c])。(单个撇号告诉 Clojure,我想要一个字符的文字序列,但并不希望执行一个包含两个参数的 (a )。)for comprehension 在我的搜索字符上创建这个序列,然后应用内部的 when 来查找匹配字符的索引。 此转换的最后一步是将代码转换为合适的 Clojure 语法,还原真实函数和语法的外观,如清单 9 所示。 清单 9. Clojure 化的代码 // Clojure-ify(defn index-filter [pred coll] (when pred (for [[index element] (indexed coll) :when (pred element)] index))) 在清单 9 中的最终的 Clojure 版本中,我将语法转换为合适的 Clojure 并添加一次升级:此函数的调用方现在可传递任何判定函数(一个返回布尔值结果的函数),而不只是检查一个空字符串。Clojure 的一个目标是实现创建可读的代码的能力(在您理解圆括号之后),而且这个函数证实了这种能力:对于带索引的集合,在您的判定与元素匹配时,将会返回索引。 Clojure 的另一个目标是使用最少量的字符来表达清楚目的;在这方面,Java 与 Clojure 相差甚远。表 2 比较了 清单 4 中的 "移动部件" 和 清单 9 中的相应部件。 表 2.比较 "移动部件" 函数 1 1 类 1 0 内部退出点 2 0 变量 3 0 分支 4 0 布尔运算符 1 0 函数调用 6 3 总计 18 4 复杂性上的差异一目了然。尽管 Clojure 代码更简单,但它也更加通用。这里,我对一个硬币翻转序列建立了索引,建模为 Clojure :h(头)和 :t(尾)关键字: (index-filter #{:h} [:t :t :h :t :h :t :t :t :h :h]) ->(2 4 8 9)
Note that the return value is a sequence of all matching index positions, not just the first. List operations in Clojure are as lazy as possible, including this one. If I only want the first value, then I can get that value from the result through (take 1), or I can print them all, as I did here.
My (index-filter) function is generic, so I can use it on numbers. For example, I can determine the first number whose Fibonacci value exceeds 1000:
(first (index-filter # (>% 1000) (fibo)-> 17
The (fibo) function returns an unrestricted but lazy sequence of Fibonacci numbers; (index-filter) finds the first value that exceeds 1000. (it turns out that the Fibonacci value of 18 is 1597. The combination of function structure, dynamic typing, inertia, and concise syntax results in more powerful functionality
Inertia
Inertia-delaying expression evaluation as much as possible-is another excellent example of functional languages adding functionality with little or no developer cost. See "functional thinking: exploring lazy computing in Java" and "functional thinking: dissecting lazy computing in depth" for lazy discussions and examples in the next generation of Java languages.
At this point, I believe you have a deeper understanding of "what is java memory and functional synergy". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.