[Transducer + Ramda] Write highly performance / functional code by using transducer-js and ramda.js libs

Tansducer-js lib

A high performance Transducers implementation for JavaScript.

Transducers are composable algorithmic transformations. They are independent from the context of their input and output sources and specify only the essence of the transformation in terms of an individual element. Because transducers are decoupled from input or output sources, they can be used in many different processes - collections, streams, channels, observables, etc. Transducers compose directly, without awareness of input or creation of intermediate aggregates.

The whole point to use transducer-js lib is because in normal FP approach, when se do:

Array
    .map
    .filter
    .reducer

We actually loop though the array 3 times. So time complexity is O(n). If you can reduce 3 times into single time. And reduce the time complexity from O(n) to O(1). It would be a huge proferemce improvement for large datasets.

Second, normal approach we are limiting ourself with Array type, we cannot call ‘mpa, filter, reduce‘ on type of Object, Map and Set. But with transducer-js, we are able to do that as well.

Ramda.js:

The primary distinguishing features of Ramda are:

  • Ramda emphasizes a purer functional style. Immutability and side-effect free functions are at the heart of its design philosophy. This can help you get the job done with simple, elegant code.
  • Ramda functions are automatically curried. This allows you to easily build up new functions from old ones simply by not supplying the final parameters.
  • The parameters to Ramda functions are arranged to make it convenient for currying. The data to be operated on is generally supplied last.

The last two points together make it very easy to build functions as sequences of simpler functions, each of which transforms the data and passes it along to the next. Ramda is designed to support this style of coding.

The whole point we are using Ramda.js is because it enforce the FP approach, and auto currying is a huge win in FP style. Also you can use loadsh/fp if you wish.

Now let‘s see what kind of problem we want to solve:

lets say we have two string:

`hostname, username `
`
    10.1.10.1, zwan
    10.1.11.1, wan

`

And we want to apply so transform function to those string and the final output should be:

[ { hostname: ‘10.1.10.1‘, username: ‘zwan‘ },
  { hostname: ‘10.1.11.1‘, username: ‘wan‘ } ]

Now here is one of the possible solution by only using ramda.js:

var R = require("ramda");

const headerStr = `hostname, username `;
const contentStr = `
    10.1.10.1, zwan
    10.1.11.1, wan

`;

/**
 * Working with Ramda.js
 */
const stringToArray = R.compose(
    R.map(R.trim),
    R.filter(Boolean),
    R.split(‘,‘)
);
const transformContent = R.compose(
    R.map(stringToArray),
    R.filter(Boolean),
    R.split(‘\n‘)
);
const keyValPair = R.useWith(
    R.map,
    [
        R.zipObj,
        R.identity
    ]
);

const header = stringToArray(headerStr);
const content = transformContent(contentStr);

const res = keyValPair(header, content);
console.log(res);

The solution is fine, it should be really easy to be tested and maintained. We also able to compose the logic such as :

const stringToArray = R.compose(
    R.map(R.trim),
    R.filter(Boolean),
    R.split(‘,‘)
);
const transformContent = R.compose(
    R.map(stringToArray),
    R.filter(Boolean),
    R.split(‘\n‘)
);

The only problem (from my point of view) is the preformence.

When we call ‘R.map, R.filter‘, it actually loop though the array twice. When we call ‘R.map(stringToArray)‘, the nested loop might increase the time complxity to O(n ^2).

Here is the transducer-js comes to help.

var t = require("transducers-js");
var R = require("ramda");

const headerStr = `hostname, username `;
const contentStr = `
    10.1.10.1, zwan
    10.1.11.1, wan

`;
/**
 * Working with transducer-js + Rmada.js
 */

const stringToArr = R.compose(
    t.comp(
        t.map(R.trim),
        t.filter(R.isNil)
    ),
    R.split(‘,‘)
);
const transformCnt = R.compose(
    t.comp(
        t.map(stringToArr),
        t.filter(R.isNil)
    ),
    R.split(‘\n‘)
);
const keyValPair = R.useWith(
    R.map,
    [
        R.zipObj,
        R.identity
    ]
);
const h = stringToArr(headerStr);
const c = transformCnt(contentStr);
const res2 = keyValPair(h, c);
console.log("res2", res);

As you can see that, we replace

// from
const stringToArray = R.compose(
    R.map(R.trim),
    R.filter(Boolean),
    R.split(‘,‘)
);

// to
const stringToArr = R.compose(
    t.comp(
        t.map(R.trim),
        t.filter(R.isNil)
    ),
    R.split(‘,‘)
);

From ‘R.map, R.filter‘, loop twice to ‘t.comp(t.map, t.filter)‘ only loop once. ‘t.comp‘ helps to compose two transform opreation together. If you think further, this is not that easy task to combine filter‘s prediction function with map‘s transform function:

filter prediction:

f => (a → Boolean)

map transform:

f => (a → b)

Because the return type is not the same, so they cannot compose naturally. transducer-js helps us to make it easily.

原文地址:https://www.cnblogs.com/Answer1215/p/8290066.html

时间: 2024-11-16 16:58:11

[Transducer + Ramda] Write highly performance / functional code by using transducer-js and ramda.js libs的相关文章

There is an internal error in the React performance measurement code.Did not expect componentDidMount timer to start while render timer is still in progress for another instance

一.There is an internal error in the React performance measurement code.Did not expect componentDidMount timer to start while render timer is still in progress for another instance 二._this3._toDetail is not a function.(In ‘this3._toDetail()’,’_this3._

Unity3D Optimizing Graphics Performance for iOS

原地址:http://blog.sina.com.cn/s/blog_72b936d801013ptr.html icense Comparisons http://unity3d.com/unity/licenses#iphone Optimizing Graphics Performance http://unity3d.com/support/documentation/Manual/Optimizing Graphics Performance.html iOS A useful bac

[Vue @Component] Pass Props to Vue Functional Templates

Functional templates allow you to create components consisting of only the template tag and exposing the props passed into the template with the props object off of the template context. This approach allows you to build simple configurable templates

Code is not literature

http://www.gigamonkeys.com/code-reading/ I have started code reading groups at the last two companies I’ve worked at, Etsy and Twitter, and some folks have asked for my advice about code reading and running code reading groups. Tl;dr: don’t start a c

VS Code python初体验笔记

之前一直都是使用Notepad++来编写Python代码,后来想起来之前查资料的时候有个VS Code可以编写一些的脚本语言(js,node.js)甚至是高级编程语言(C#,PHP,JAVA,Python等)而且这是微软自家写的,这就引起我的浓烈兴趣了,查了下VS Code发现这东西不错,而且广受程序员的喜爱,不仅能够在windows上运行编写的程序,而且还能在Mac,linux平台上运行,并且开源(这从侧面说明了微软的巨大改变,其开源力度真是前所未见,我很期待微软的开源框架asp.net co

Nodejs in Visual Studio Code 10.IISNode

1.开始 Nodejs in Visual Studio Code 08.IIS : http://www.cnblogs.com/mengkzhaoyun/p/5410185.html 参考此篇内容,部署一个iisnode示例 2.将Node.js Express框架示例程序部署在IISNode中  创建一个Express示例程序 $ cd D:\Libraries\Documents\Visual Studio Code $ express myapp create : myapp crea

Visual Studio Code 配置指南

Visual Studio Code (简称 VS Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器.在我看来它是「一款完美的编辑器」. 本文是有关 VS Code 的特性介绍与配置指南,相关设置主要针对 Mac OS X 平台.在快捷键部分, ? 指 Command 键,? 指 Shift 键,? 指 Control 键,? 指 Option/Alt 键. 1. Visual Studio Code 特性简介 1.1 Git 集成 如上图所示,VS Code 默认集成了 Git

使用TypeScript拓展你自己的VS Code!

0x00 前言 在前几天的美国纽约,微软举行了Connect(); //2015大会.通过这次大会,我们可以很高兴的看到微软的确变得更加开放也更加务实了.当然,会上放出了不少新产品和新功能,其中就包括了VS Code的beta版本.而且微软更进一步,已经在github将VS Code的代码开源了.除了这些让人兴奋的消息,我们还应该注意到VS Code提供了对拓展的支持.所以本文就来聊一聊使用TypeScript开发VS Code拓展的话题吧. 本文所使用的拓展的应用商店页面: https://m

Visual Studio Code——Angular2 Hello World 之 2.0

最近看到一篇用Visual Studio Code开发Angular2的文章,也是一篇入门教程,地址为:使用Visual Studio Code開發Angular 2專案.这里按部就班的做了一遍,感觉很方便,并且没有遇到楼主的一些问题,应该是安装环境有些不同.这里只为记录一下.再次感谢! 一.随便新建一个目录,这里为:F:\Visual Studio Code\angular2_1,并用Visual Studio Code 二.依次新建如下四个文件,参考https://angular.cn/do