diff --git a/.npmignore b/.npmignore
index e0f6eb0..fdc151e 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,8 +1,8 @@
+*.sh
+*.yml
.*
benchmark
-bower_components
bower.json
-*.yml
-compile
+bower_components
img
test
diff --git a/README.md b/README.md
index b22c1bf..0b1319d 100644
--- a/README.md
+++ b/README.md
@@ -1,49 +1,73 @@
-# fast-format [](https://circleci.com/gh/knowledgecode/fast-format)
-This is a simplified version of Node.js `util.format()`. This supports only `%s` placeholder, but faster than that. This will be the best solution if you need speed rather than complex formatting.
+# fast-format
+[](https://circleci.com/gh/knowledgecode/fast-format)
+
+This is a string formatter like `util.format()` method in Node.js, supports just only `%s` placeholder but accordingly faster than that. It will be one of the best solution if need a speed rather than complex formatting.
## Usage
-Same as Node.js `util.format()`.
+Same as `util.format()` method.
```js
format(formatString[, ...])
```
+If use one formatting repeatedly, recommended to compile the `formatString` in advance.
+```js
+format.compile(formatString)
+```
+
## Example
```js
-var s = format('%s, %s!', 'Hello', 'world');
+let s = format('%s, %s!', 'Hello', 'world');
console.log(s); // => 'Hello, world!'
```
+```js
+let f = format.compile('%s, %s!');
+let s1 = f('Hello', 'world');
+console.log(s1); // => 'Hello, world!'
+let s2 = f('Howdy', 'World');
+console.log(s2); // => 'Howdy, World!'
+```
## Benchmark
```js
-var i, len, s = Date.now();
-for (i = 0, len = 10000000; i < len; i++) {
+// Bench 1
+let s = Date.now();
+for (let i = 0, len = 100000000; i < len; i++) {
format('i = %s, len = %s', i, len);
}
console.log(Date.now() - s);
```
+```js
+// Bench 2
+let s = Date.now();
+let f = format.compile('i = %s, len = %s');
+for (let i = 0, len = 100000000; i < len; i++) {
+ f(i, len);
+}
+console.log(Date.now() - s);
+```
-*environment1: MacBook Air Early 2015 + Node.js v0.12.5*
+*environment1: Core i7 2.2GHz + Node.js v6.9.5*
-
+
-| module | time |
-|-------------|-------------|
-| fast-format | 2,072 msec |
-| util.format | 11,571 msec |
-| sprintf-js | 19,438 msec |
+| module | time | bench |
+|-------------|-------------|:-----:|
+| fast-format | 12,388 msec | 2 |
+| fast-format | 22,039 msec | 1 |
+| util.format | 28,659 msec | 1 |
---
-*environment2: Core i7 2.5GHz Windows 8.1 Pro + Internet Explorer 11*
+*environment2: Core i7 2.2GHz + Google Chrome 56.0.2924.87*
-
+
-| module | time |
-|-------------|-------------|
-| fast-format | 25,302 msec |
-| util.format | 40,550 msec |
-| sprintf-js | 58,133 msec |
+| module | time | bench |
+|-------------|-------------|:-----:|
+| fast-format | 12,898 msec | 2 |
+| fast-format | 22,705 msec | 1 |
+| util.format | 99,103 msec | 1 |
-[sprintf-js](https://github.com/alexei/sprintf.js) is a JavaScript sprintf implementation for the browser and Node.js. It is slow but might not be inevitable because a high functional module.
+The `util.format()` method was converted with `Browserify` to run on the browser.
## Installation
### via npm
@@ -51,14 +75,18 @@ console.log(Date.now() - s);
npm install fast-format --save
```
-### via bower
+### via Bower
```sh
bower install fast-format
```
+### directly (in case of the browser)
+``` html
+
+```
+
## Browser Support
-Chrome, Firefox, Safari, Opera, and Internet Explorer 6+
+Google Chrome, Firefox, Safari, Opera, Microsoft Edge and IE 6+
## License
MIT
-
diff --git a/bower.json b/bower.json
index f6a6df7..8428f5d 100644
--- a/bower.json
+++ b/bower.json
@@ -1,12 +1,12 @@
{
"name": "fast-format",
"main": "fast-format.min.js",
- "version": "0.1.1",
+ "version": "0.2.0",
"homepage": "https://github.com/knowledgecode/fast-format",
"authors": [
"knowledgecode "
],
- "description": "A simplified version of Node.js util.format()",
+ "description": "A fast, simple string formatter like util.format() method in Node.js",
"moduleType": [
"amd",
"globals",
@@ -15,11 +15,11 @@
"ignore": [
"**/.*",
"bower_components",
- "compile",
"img",
"node_modules",
"test",
"*.json",
+ "*.sh",
"*.yml"
],
"keywords": [
diff --git a/circle.yml b/circle.yml
index 31badd0..e9bdad1 100644
--- a/circle.yml
+++ b/circle.yml
@@ -1,3 +1,3 @@
machine:
node:
- version: 0.12.0
+ version: 6.1.0
diff --git a/compile b/compile.sh
similarity index 61%
rename from compile
rename to compile.sh
index 0a32904..df312cb 100755
--- a/compile
+++ b/compile.sh
@@ -1,9 +1,9 @@
#!/bin/sh -eu
-url="http://closure-compiler.appspot.com/compile"
+url="https://closure-compiler.appspot.com/compile"
dir=`dirname $0`
-input="${dir}/fast-format.js"
-output="${dir}/fast-format.min.js"
+input=${dir}/$1
+output=${dir}/$2
js_code=`cat $input`
curl --silent \
diff --git a/fast-format.js b/fast-format.js
index 6aa9576..80f8b00 100644
--- a/fast-format.js
+++ b/fast-format.js
@@ -1,17 +1,41 @@
/**
- * @preserve fast-format.js (C) 2015 KNOWLEDGECODE | MIT
+ * @preserve fast-format.js (C) KNOWLEDGECODE | MIT
*/
(function (global) {
'use strict';
var f = function (format) {
- var i, len, argc = arguments.length, v = (format + '').split('%s'), r = argc ? v[0] : '';
- for (i = 1, len = v.length, argc--; i < len; i++) {
- r += (i > argc ? '%s' : arguments[i]) + v[i];
+ var argc = arguments.length, v = (argc ? format + '' : '').split('%s'), i = 1, len = v.length, r = v[0];
+ if (argc > len) {
+ argc = len;
+ }
+ while (i < argc) {
+ r += arguments[i] + v[i++];
+ }
+ while (i < len) {
+ r += '%s' + v[i++];
}
return r;
};
+ f.compile = function (format) {
+ var v = (arguments.length ? format + '' : '').split('%s'), len = v.length;
+ return function () {
+ var i = 0, argc = arguments.length, r = v[0];
+ if (argc > len - 1) {
+ argc = len - 1;
+ }
+ while (i < argc) {
+ r += arguments[i] + v[++i];
+ }
+ i++;
+ while (i < len) {
+ r += '%s' + v[i++];
+ }
+ return r;
+ };
+ };
+
if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = f;
} else if (typeof global.define === 'function' && global.define.amd) {
diff --git a/fast-format.min.js b/fast-format.min.js
index 502b958..ecdbab7 100644
--- a/fast-format.min.js
+++ b/fast-format.min.js
@@ -1,4 +1,5 @@
/*
- fast-format.js (C) 2015 KNOWLEDGECODE | MIT
+ fast-format.js (C) KNOWLEDGECODE | MIT
*/
-(function(a){var c=function(a){var b,c,d=arguments.length,e=(a+"").split("%s"),f=d?e[0]:"";b=1;c=e.length;for(d--;bd?"%s":arguments[b])+e[b];return f};"object"===typeof module&&"object"===typeof module.exports?module.exports=c:"function"===typeof a.define&&a.define.amd?a.define([],function(){return c}):a.format=c})(this);
+(function(a){var f=function(a){var c=arguments.length,d=(c?a+"":"").split("%s"),b=1,g=d.length,e=d[0];for(c>g&&(c=g);bd-1&&(a=d-1);b
-
-
-
+
+
+
-
- fast-format
- util.format
- sprintf-js
+
+ fast-format
+ + compile
+ fast-format
+ util.format
-
+
0
- 15,000
- 30,000
- 45,000
- 60,000
+ 7,500
+ 15,000
+ 22,500
+ 30,000
[msec]
diff --git a/img/graph2.svg b/img/graph2.svg
index 9f55bef..67b4864 100644
--- a/img/graph2.svg
+++ b/img/graph2.svg
@@ -30,22 +30,23 @@
-
-
-
+
+
+
-
- fast-format
- util.format
- + browserify
- sprintf-js
+
+ fast-format
+ + compile
+ fast-format
+ util.format
+ + browserify
-
+
0
- 15,000
- 30,000
- 45,000
- 60,000
+ 25,000
+ 50,000
+ 75,000
+ 100,000
[msec]
diff --git a/package.json b/package.json
index 6e8ce74..2c14da1 100644
--- a/package.json
+++ b/package.json
@@ -1,19 +1,19 @@
{
"name": "fast-format",
- "version": "0.1.1",
- "description": "A simplified version of Node.js util.format()",
+ "version": "0.2.0",
+ "description": "A fast, simple string formatter like util.format() method in Node.js",
"main": "fast-format.js",
"directories": {
"test": "test"
},
"devDependencies": {
"expect.js": "^0.3.1",
- "mocha": "^2.2.5",
- "mocha-phantomjs": "^3.5.3"
+ "mocha": "^2.5.3",
+ "mocha-phantomjs": "^4.1.0"
},
"scripts": {
"test": "mocha test/test.js && mocha-phantomjs test/test.html",
- "compile": "./compile"
+ "compile": "./compile.sh fast-format.js fast-format.min.js"
},
"keywords": [
"fast",
diff --git a/test/test.js b/test/test.js
index eaecaa7..76074a5 100644
--- a/test/test.js
+++ b/test/test.js
@@ -73,5 +73,95 @@
});
});
-}(this));
+ describe('format.compile', function () {
+ it('1 replace', function () {
+ var f = format.compile('%s');
+ expect(f('hello')).to.eql('hello');
+ });
+ it('2 insert', function () {
+ var f = format.compile('%shello');
+ expect(f('hello')).to.eql('hellohello');
+ });
+ it('3 append', function () {
+ var f = format.compile('hello%s');
+ expect(f('hello')).to.eql('hellohello');
+ });
+ it('4 insert2', function () {
+ var f = format.compile('hello%shello');
+ expect(f('hello')).to.eql('hellohellohello');
+ });
+ it('5 join', function () {
+ var f = format.compile('%s%s');
+ expect(f('he', 'llo')).to.eql('hello');
+ });
+ it('6 replace2', function () {
+ var f = format.compile(' %s %s ');
+ expect(f('he', 'llo')).to.eql(' he llo ');
+ });
+ it('7 %s', function () {
+ var f = format.compile('%s');
+ expect(f('%s')).to.eql('%s');
+ });
+ it('8 number', function () {
+ var f = format.compile('%s');
+ expect(f(100)).to.eql('100');
+ });
+ it('9 boolean', function () {
+ var f = format.compile('%s');
+ expect(f(true)).to.eql('true');
+ });
+ it('10 date', function () {
+ var f = format.compile('%s');
+ expect(f(new Date(2015, 5, 28))).to.contain('Sun Jun 28 2015 00:00:00');
+ });
+ it('11 array', function () {
+ var f = format.compile('%s');
+ expect(f([1, 2, 3])).to.eql('1,2,3');
+ });
+ it('12 object', function () {
+ var f = format.compile('%s');
+ expect(f({ key: 'value' })).to.eql('[object Object]');
+ });
+ it('13 NaN', function () {
+ var f = format.compile('%s');
+ expect(f(NaN)).to.eql('NaN');
+ });
+ it('14 function', function () {
+ var f = format.compile('%s');
+ expect(f(function () {})).to.eql('function () {}');
+ });
+ it('15 null', function () {
+ var f = format.compile('%s');
+ expect(f(null)).to.eql('null');
+ });
+ it('16 undefined', function () {
+ var f = format.compile('%s');
+ expect(f(undefined)).to.eql('undefined');
+ });
+ it('17 excess', function () {
+ var f = format.compile('%s %s %s %s');
+ expect(f('1', '2', '3', '4', '5')).to.eql('1 2 3 4');
+ });
+ it('18 deficiency', function () {
+ var f = format.compile('%s %s %s %s');
+ expect(f('1', '2', '3')).to.eql('1 2 3 %s');
+ });
+ it('19 no values', function () {
+ var f = format.compile('%s %s %s %s');
+ expect(f()).to.eql('%s %s %s %s');
+ });
+ it('20 %', function () {
+ var f = format.compile('%');
+ expect(f()).to.eql('%');
+ });
+ it('21 empty', function () {
+ var f = format.compile();
+ expect(f()).to.eql('');
+ });
+ it('22 not supported', function () {
+ var f = format.compile('%d, %j');
+ expect(f(10, { key: 'value' })).to.eql('%d, %j');
+ });
+ });
+}(this));