ko.viewmodel vs ko.mapping - viewmodel creation (v49)

Revision 49 of this benchmark created on


Description

Performance comparison between the knockout mapping plugins ko.viewmodel and ko.mapping.

Preparation HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<script>
-//v2.0.3 - C 2013, Dave Herren, License: MIT 
(function(){function y(b,g){var e=b?b[g.full]||b[g.parent]||b[g.name]||{}:{};p&&p(g,e,b);return e}function r(b){return null===b||void 0===b}function u(b){return null===b||void 0===b||b.constructor===String||b.constructor===Number||b.constructor===Boolean||b instanceof Date}function n(b,g,e,c){var f,a,d,h,k,l,m;c=c||y(g,e);if(f=c.custom)l=!0,"function"===typeof f?(a=f(b),r(a)||(a.___$mapCustom=f)):(a=f.map(b),r(a)||(a.___$mapCustom=f.map,f.unmap&&(a.___$unmapCustom=f.unmap)));else if(c.append)l=!0,
a=b;else{if(c.exclude)return l=!0,v;if(u(b))a=e.parentIsArray?b:B(b);else if(b instanceof Array){a=[];d=0;for(f=b.length;d<f;d++)a[d]=n(b[d],g,{name:"[i]",parent:e.name+"[i]",full:e.full+"[i]",parentIsArray:!0});if(!e.parentIsArray||z){h={name:"[i]",parent:e.name+"[i]",full:e.full+"[i]",parentIsArray:!0};a=C(a);if(b=c.arrayChildId)a.___$childIdName=b;a.pushFromModel=function(b){b=n(b,g,h);a.push(b)};a.unshiftFromModel=function(b){b=n(b,g,h);a.unshift(b)};a.popToModel=function(b){b=a.pop();return s(b,
h)};a.shiftToModel=function(b){b=a.shift();return s(b,h)}}}else if(b.constructor===Object)for(d in a={},b)h={name:d,parent:("[i]"===e.name?e.parent:e.name)+"."+d,full:e.full+"."+d},m=b[d],(f=u(m)?y(g,h):void 0)&&f.custom?(a.___$customChildren=a.___$customChildren||{},a.___$customChildren[d]=f.custom,a[d]="function"===typeof f.custom?f.custom(b[d]):f.custom.map(b[d])):(f=n(m,g,h,f),f!==v&&(a[d]=f))}if(!l&&(k=c.extend))"function"===typeof k?a=k(a)||a:k.constructor===Object&&("function"===typeof k.map&&
(a=k.map(a)||a),"function"===typeof k.unmap&&(a.___$unmapExtend=k.unmap));return a}function s(b,g){var e,c,f,a=q(b),d;d=b!==a;p&&p(g);if(!d&&b&&b.constructor===Function)return v;if(b&&b.___$unmapCustom)e=b.___$unmapCustom(b);else if(d&&u(a)||r(a))e=a;else if(a instanceof Array){e=[];c=0;for(f=a.length;c<f;c++)e[c]=s(a[c],{name:"[i]",parent:g.name+"[i]",full:g.full+"[i]"})}else if(a.constructor===Object)for(c in e={},a){if("___$"!==c.substr(0,4))if(b.___$customChildren&&b.___$customChildren[c]&&b.___$customChildren[c].unmap)e[c]=
b.___$customChildren[c].unmap(a[c]);else if(d=a[c],!ko.isComputed(d)&&!((f=q(d))&&f.constructor===Function))d=s(d,{name:c,parent:("[i]"===g.name?g.parent:g.name)+"."+c,full:g.full+"."+c}),d!==v&&(e[c]=d)}else!d&&"function"!==typeof a&&(e=a);b&&b.___$unmapExtend&&(e=b.___$unmapExtend(e,b));return e}function t(b,g,e,c,f){var a,d,h,k,l,m,n,j=q(g);d=g!==j;p&&p(e);if(d&&r(j)^r(b))g(b);else if(b&&j&&j.constructor==Object&&b.constructor===Object)for(a in b)g.___$customChildren&&g.___$customChildren[a]?(c=
g.___$customChildren[a].map||g.___$customChildren[a],j[a]=c(b[a])):(c=j[a],!d&&j.hasOwnProperty(a)&&(u(c)||c&&c.constructor===Array)?j[a]=b[a]:c&&"function"===typeof c.___$mapCustom?A(c)?(h=c.___$mapCustom(b[a],c),h=q(h),c(h)):j[a]=c.___$mapCustom(b[a],c):r(b[a])&&j[a]&&j[a].constructor===Object?j[a]=b[a]:f?(c=function(a,b,c){return function(){t(a[c],j[c],{name:c,parent:("[i]"===e.name?e.parent:e.name)+"."+c,full:e.full+"."+c},j,f);f(f()-1)}}(b,g,a),f(f()+1),setTimeout(c,0)):t(b[a],j[a],{name:a,parent:("[i]"===
e.name?e.parent:e.name)+"."+a,full:e.full+"."+a}));else if(j&&j instanceof Array)if(n=g.___$childIdName){h=[];k=[];for(a=b.length-1;0<=a;a--){l=b[a][n];for(d=j.length-1;0<=d;d--)if(c=j[d],m=q(c),m=q(m[n]),m===l){c.___$mapCustom?ko.isObservable(c)?(l=c.___$mapCustom(b[a],c),A(l)&&l!=c&&c(q(l))):j[d]=c.___$mapCustom(b[a],c):f?(c=function(a,b,c,d){return function(){t(a[c],j[d],{name:"[i]",parent:e.name+"[i]",full:e.full+"[i]"},void 0,f);f(f()-1)}}(b,g,a,d),f(f()+1),setTimeout(c,0)):t(b[a],j[d],{name:"[i]",
parent:e.name+"[i]",full:e.full+"[i]"});k[d]=!0;h[a]=!0;break}}for(d=j.length-1;0<=d;d--)k[d]||g.splice(d,1);for(a=b.length-1;0<=a;a--)h[a]||g.pushFromModel(b[a])}else if(h=[],d=g.___$mapCustom,"function"===typeof d){a=0;for(c=b.length;a<c;a++)h[a]=b[a];g(d(h))}else{g(h);a=0;for(c=b?b.length:0;a<c;a++)g.pushFromModel(b[a])}else d&&g(b);if("{root}"===e.name&&f)return{onComplete:function(a){a&&"function"==typeof a&&(f?ko.computed(function(){a&&0===f()&&(a(),a=void 0)}).extend({throttle:50}):a())}}}
function w(b,g){z=b.makeChildArraysObservable;window.console&&b.logging?(console.log(g),p=function(b,c,f){console.log("- "+(c&&c.settingType?c.settingType+" "+b.full+" (matched: '"+((f[b.full]?b.full:"")||(f[b.parent]?b.parent:"")||b.name)+"')":"default "+b.full))}):p=void 0}var q=ko.utils.unwrapObservable,A=ko.isObservable,B=ko.observable,C=ko.observableArray,x={name:"{root}",parent:"{root}",full:"{root}"},p,z,v=function(){};ko.viewmodel={options:{makeChildArraysObservable:!0,logging:!1},fromModel:function(b,
g){var e={},c=g?g.shared||{}:{},f,a,d,h,k,l,m;for(k in g)if(f=g[k]||{},"shared"!==k)if(f instanceof Array){a=0;for(h=f.length;a<h;a++)d=f[a],e[d]=e[d]||{},e[d][k]=!0,e[d].settingType=e[d].settingType?"multiple":k}else if(f.constructor===Object)for(d in f){e[d]=e[d]||{};a=f[d];if((a="arrayChildId"!==k&&a&&a.constructor===String&&c[a]?c[a]:a)&&a.constructor===Object)for(l in a)if((m=a[l])&&m.constructor==String&&c[m])a[l]=c[m];e[d][k]=a;e[d].settingType=e[d].settingType?"multiple":k}w(this.options,
"Mapping From Model");return n(b,e,x)},toModel:function(b){w(this.options,"Mapping To Model");return s(b,x)},updateFromModel:function(b,g,e){e=e?ko.observable(0):void 0;w(this.options,"Update From Model");return t(g,b,x,void 0,e)}}})();
</script>

Setup

var numberOfArrayRecords = 100,
    viewmodel = null,
    model = {
        items:[]
    };
    
    for(var x = 0; x < numberOfArrayRecords; x++){
        model.items.push({
            string:"Test",
            number:4,
            anotherObject:{
               items:[{id:4, name:"Test"},{id:7, name:"Test2"}] 
            }      
        });   
            
    }

Test runner

Ready to run.

Testing in
TestOps/sec
ko.mapping
viewmodel = ko.mapping.fromJS(model);
ready
ko.viewmodel
viewmodel = ko.viewmodel.fromModel(model);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.