租房小程序前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
3.2 KiB

6 months ago
2 months ago
6 months ago
  1. # reusify
  2. [![npm version][npm-badge]][npm-url]
  3. Reuse your objects and functions for maximum speed. This technique will
  4. make any function run ~10% faster. You call your functions a
  5. lot, and it adds up quickly in hot code paths.
  6. ```
  7. $ node benchmarks/createNoCodeFunction.js
  8. Total time 53133
  9. Total iterations 100000000
  10. Iteration/s 1882069.5236482036
  11. $ node benchmarks/reuseNoCodeFunction.js
  12. Total time 50617
  13. Total iterations 100000000
  14. Iteration/s 1975620.838848608
  15. ```
  16. The above benchmark uses fibonacci to simulate a real high-cpu load.
  17. The actual numbers might differ for your use case, but the difference
  18. should not.
  19. The benchmark was taken using Node v6.10.0.
  20. This library was extracted from
  21. [fastparallel](http://npm.im/fastparallel).
  22. ## Example
  23. ```js
  24. var reusify = require('reusify')
  25. var fib = require('reusify/benchmarks/fib')
  26. var instance = reusify(MyObject)
  27. // get an object from the cache,
  28. // or creates a new one when cache is empty
  29. var obj = instance.get()
  30. // set the state
  31. obj.num = 100
  32. obj.func()
  33. // reset the state.
  34. // if the state contains any external object
  35. // do not use delete operator (it is slow)
  36. // prefer set them to null
  37. obj.num = 0
  38. // store an object in the cache
  39. instance.release(obj)
  40. function MyObject () {
  41. // you need to define this property
  42. // so V8 can compile MyObject into an
  43. // hidden class
  44. this.next = null
  45. this.num = 0
  46. var that = this
  47. // this function is never reallocated,
  48. // so it can be optimized by V8
  49. this.func = function () {
  50. if (null) {
  51. // do nothing
  52. } else {
  53. // calculates fibonacci
  54. fib(that.num)
  55. }
  56. }
  57. }
  58. ```
  59. The above example was intended for synchronous code, let's see async:
  60. ```js
  61. var reusify = require('reusify')
  62. var instance = reusify(MyObject)
  63. for (var i = 0; i < 100; i++) {
  64. getData(i, console.log)
  65. }
  66. function getData (value, cb) {
  67. var obj = instance.get()
  68. obj.value = value
  69. obj.cb = cb
  70. obj.run()
  71. }
  72. function MyObject () {
  73. this.next = null
  74. this.value = null
  75. var that = this
  76. this.run = function () {
  77. asyncOperation(that.value, that.handle)
  78. }
  79. this.handle = function (err, result) {
  80. that.cb(err, result)
  81. that.value = null
  82. that.cb = null
  83. instance.release(that)
  84. }
  85. }
  86. ```
  87. Also note how in the above examples, the code, that consumes an instance of `MyObject`,
  88. reset the state to initial condition, just before storing it in the cache.
  89. That's needed so that every subsequent request for an instance from the cache,
  90. could get a clean instance.
  91. ## Why
  92. It is faster because V8 doesn't have to collect all the functions you
  93. create. On a short-lived benchmark, it is as fast as creating the
  94. nested function, but on a longer time frame it creates less
  95. pressure on the garbage collector.
  96. ## Other examples
  97. If you want to see some complex example, checkout [middie](https://github.com/fastify/middie) and [steed](https://github.com/mcollina/steed).
  98. ## Acknowledgements
  99. Thanks to [Trevor Norris](https://github.com/trevnorris) for
  100. getting me down the rabbit hole of performance, and thanks to [Mathias
  101. Buss](http://github.com/mafintosh) for suggesting me to share this
  102. trick.
  103. ## License
  104. MIT
  105. [npm-badge]: https://badge.fury.io/js/reusify.svg
  106. [npm-url]: https://badge.fury.io/js/reusify