mirror of https://github.com/vuejs/vue.git
				
				
				
			observer benchmarks and tests
This commit is contained in:
		
							parent
							
								
									8bcc3834a9
								
							
						
					
					
						commit
						b9f2c1ac39
					
				| 
						 | 
				
			
			@ -0,0 +1,306 @@
 | 
			
		|||
var Observer = require('../src/observer/observer')
 | 
			
		||||
var Emitter = require('../src/emitter')
 | 
			
		||||
var OldObserver = require('../../vue/src/observer')
 | 
			
		||||
var sideEffect = 0
 | 
			
		||||
var runs = 1000
 | 
			
		||||
function cb () {
 | 
			
		||||
  sideEffect++
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var loadTime = getNano()
 | 
			
		||||
 | 
			
		||||
function getNano () {
 | 
			
		||||
  var hr = process.hrtime()
 | 
			
		||||
  return hr[0] * 1e9 + hr[1]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function now () {
 | 
			
		||||
  return (getNano() - loadTime) / 1e6
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function bench (desc, fac, run) {
 | 
			
		||||
  var objs = []
 | 
			
		||||
  for (var i = 0; i < runs; i++) {
 | 
			
		||||
    objs.push(fac(i))
 | 
			
		||||
  }
 | 
			
		||||
  var s = now()
 | 
			
		||||
  for (var i = 0; i < runs; i++) {
 | 
			
		||||
    run(objs[i])
 | 
			
		||||
  }
 | 
			
		||||
  var passed = now() - s
 | 
			
		||||
  console.log(desc + ' - ' + (16 / (passed / runs)).toFixed(2) + ' ops/frame')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'observe (simple object)        ',
 | 
			
		||||
  function (i) {
 | 
			
		||||
    return {a:i}
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    new Observer().observe('', o)
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old observe (simple object)    ',
 | 
			
		||||
  function (i) {
 | 
			
		||||
    return {a:i}
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    OldObserver.observe(o, '', new Emitter())
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'observe (3 nested objects)     ',
 | 
			
		||||
  function (i) {
 | 
			
		||||
    return {a:{b:{c:i}}}
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    new Observer().observe('', o)
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old observe (3 nested objects) ',
 | 
			
		||||
  function (i) {
 | 
			
		||||
    return {a:{b:{c:i}}}
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    OldObserver.observe(o, '', new Emitter())
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'observe (array, 3 objects)     ',
 | 
			
		||||
  function (i) {
 | 
			
		||||
    return [{a:i}, {a:i+1}, {a:i+2}]
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    new Observer().observe('', o)
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old observe (array, 3 objects) ',
 | 
			
		||||
  function (i) {
 | 
			
		||||
    return [{a:i}, {a:i+1}, {a:i+2}]
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    OldObserver.observe(o, '', new Emitter())
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'observe (array, 30 objects)    ',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = [], i = 30
 | 
			
		||||
    while (i--) {
 | 
			
		||||
      a.push({a:i})
 | 
			
		||||
    }
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    new Observer().observe('', o)
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old observe (array, 30 objects)',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = [], i = 30
 | 
			
		||||
    while (i--) {
 | 
			
		||||
      a.push({a:i})
 | 
			
		||||
    }
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    OldObserver.observe(o, '', new Emitter())
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
Observer.emitGet = true
 | 
			
		||||
OldObserver.shouldGet = true
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'simple get    ',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = {a:1}
 | 
			
		||||
    var ob = new Observer()
 | 
			
		||||
    ob.observe('', a)
 | 
			
		||||
    ob.on('get', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    var v = o.a
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old simple get',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = {a:1}
 | 
			
		||||
    var ob = new Emitter()
 | 
			
		||||
    OldObserver.observe(a, '', ob)
 | 
			
		||||
    ob.on('get', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    var v = o.a
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'nested get    ',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = {a:{b:{c:1}}}
 | 
			
		||||
    var ob = new Observer()
 | 
			
		||||
    ob.observe('', a)
 | 
			
		||||
    ob.on('get', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    var v = o.a.b.c
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old nested get',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = {a:{b:{c:1}}}
 | 
			
		||||
    var ob = new Emitter()
 | 
			
		||||
    OldObserver.observe(a, '', ob)
 | 
			
		||||
    ob.on('get', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    var v = o.a.b.c
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
Observer.emitGet = false
 | 
			
		||||
OldObserver.shouldGet = false
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'simple set    ',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = {a:1}
 | 
			
		||||
    var ob = new Observer()
 | 
			
		||||
    ob.observe('', a)
 | 
			
		||||
    ob.on('set', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    o.a = 12345
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old simple set',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = {a:1}
 | 
			
		||||
    var ob = new Emitter()
 | 
			
		||||
    OldObserver.observe(a, '', ob)
 | 
			
		||||
    ob.on('set', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    o.a = 12345
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'nested set    ',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = {a:{b:{c:1}}}
 | 
			
		||||
    var ob = new Observer()
 | 
			
		||||
    ob.observe('', a)
 | 
			
		||||
    ob.on('set', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    o.a.b.c = 2
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old nested set',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = {a:{b:{c:1}}}
 | 
			
		||||
    var ob = new Emitter()
 | 
			
		||||
    OldObserver.observe(a, '', ob)
 | 
			
		||||
    ob.on('set', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    o.a.b.c = 2
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'array mutation (5 objects)     ',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = [], i = 5
 | 
			
		||||
    while (i--) {
 | 
			
		||||
      a.push({a:i})
 | 
			
		||||
    }
 | 
			
		||||
    var ob = new Observer()
 | 
			
		||||
    ob.observe('', a)
 | 
			
		||||
    ob.on('mutation', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    o.reverse()
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old array mutation (5 objects) ',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = [], i = 5
 | 
			
		||||
    while (i--) {
 | 
			
		||||
      a.push({a:i})
 | 
			
		||||
    }
 | 
			
		||||
    var ob = new Emitter()
 | 
			
		||||
    OldObserver.observe(a, '', ob)
 | 
			
		||||
    ob.on('mutation', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    o.reverse()
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'array mutation (50 objects)    ',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = [], i = 50
 | 
			
		||||
    while (i--) {
 | 
			
		||||
      a.push({a:i})
 | 
			
		||||
    }
 | 
			
		||||
    var ob = new Observer()
 | 
			
		||||
    ob.observe('', a)
 | 
			
		||||
    ob.on('mutation', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    o.reverse()
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
bench(
 | 
			
		||||
  'old array mutation (50 objects)',
 | 
			
		||||
  function () {
 | 
			
		||||
    var a = [], i = 50
 | 
			
		||||
    while (i--) {
 | 
			
		||||
      a.push({a:i})
 | 
			
		||||
    }
 | 
			
		||||
    var ob = new Emitter()
 | 
			
		||||
    OldObserver.observe(a, '', ob)
 | 
			
		||||
    ob.on('mutation', cb)
 | 
			
		||||
    return a
 | 
			
		||||
  },
 | 
			
		||||
  function (o) {
 | 
			
		||||
    o.reverse()
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +1,18 @@
 | 
			
		|||
var Observer = require('../../src/observer/observer')
 | 
			
		||||
var delimiter = Observer.pathDelimiter
 | 
			
		||||
 | 
			
		||||
function path (p) {
 | 
			
		||||
  return p.replace(/\./g, '\b')
 | 
			
		||||
}
 | 
			
		||||
var u = undefined
 | 
			
		||||
Observer.pathDelimiter = '.'
 | 
			
		||||
 | 
			
		||||
describe('Observer', function () {
 | 
			
		||||
 | 
			
		||||
  var spy
 | 
			
		||||
  beforeEach(function () {
 | 
			
		||||
    spy = jasmine.createSpy()
 | 
			
		||||
    spy = jasmine.createSpy('observer')
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  it('get', function () {
 | 
			
		||||
 | 
			
		||||
    Observer.emitGet = true
 | 
			
		||||
 | 
			
		||||
    var obj = {
 | 
			
		||||
      a: 1,
 | 
			
		||||
      b: {
 | 
			
		||||
| 
						 | 
				
			
			@ -23,13 +23,15 @@ describe('Observer', function () {
 | 
			
		|||
    ob.on('get', spy)
 | 
			
		||||
 | 
			
		||||
    var t = obj.a
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('a', undefined, undefined)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('a', u, u)
 | 
			
		||||
    expect(spy.callCount).toEqual(1)
 | 
			
		||||
 | 
			
		||||
    t = obj.b.c
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('b', undefined, undefined)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith(path('b.c'), undefined, undefined)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('b', u, u)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('b.c', u, u)
 | 
			
		||||
    expect(spy.callCount).toEqual(3)
 | 
			
		||||
 | 
			
		||||
    Observer.emitGet = false
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  it('set', function () {
 | 
			
		||||
| 
						 | 
				
			
			@ -43,20 +45,27 @@ describe('Observer', function () {
 | 
			
		|||
    ob.on('set', spy)
 | 
			
		||||
 | 
			
		||||
    obj.a = 3
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('a', 3, undefined)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('a', 3, u)
 | 
			
		||||
    expect(spy.callCount).toEqual(1)
 | 
			
		||||
 | 
			
		||||
    obj.b.c = 4
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith(path('b.c'), 4, undefined)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('b.c', 4, u)
 | 
			
		||||
    expect(spy.callCount).toEqual(2)
 | 
			
		||||
 | 
			
		||||
    var newB = { c: 5 }
 | 
			
		||||
    obj.b = newB
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('b', newB, undefined)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('b', newB, u)
 | 
			
		||||
    expect(spy.callCount).toEqual(3)
 | 
			
		||||
 | 
			
		||||
    // same value set should not emit events
 | 
			
		||||
    obj.a = 3
 | 
			
		||||
    expect(spy.callCount).toEqual(3)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  it('array get', function () {
 | 
			
		||||
 | 
			
		||||
    Observer.emitGet = true
 | 
			
		||||
 | 
			
		||||
    var obj = {
 | 
			
		||||
      arr: [{a:1}, {a:2}]
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -64,17 +73,52 @@ describe('Observer', function () {
 | 
			
		|||
    ob.on('get', spy)
 | 
			
		||||
 | 
			
		||||
    var t = obj.arr[0].a
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith(path('arr'), undefined, undefined)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith(path('arr.0.a'), undefined, undefined)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('arr', u, u)
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('arr.0.a', u, u)
 | 
			
		||||
    expect(spy.callCount).toEqual(2)
 | 
			
		||||
 | 
			
		||||
    Observer.emitGet = false
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  it('array set', function () {
 | 
			
		||||
    // body...
 | 
			
		||||
    var obj = {
 | 
			
		||||
      arr: [{a:1}, {a:2}]
 | 
			
		||||
    }
 | 
			
		||||
    var ob = Observer.create(obj)
 | 
			
		||||
    ob.on('set', spy)
 | 
			
		||||
 | 
			
		||||
    obj.arr[0].a = 2
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('arr.0.a', 2, u)
 | 
			
		||||
 | 
			
		||||
    // set events after mutation
 | 
			
		||||
    obj.arr.reverse()
 | 
			
		||||
    obj.arr[0].a = 3
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('arr.0.a', 3, u)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  it('array mutate', function () {
 | 
			
		||||
    // body...
 | 
			
		||||
    var arr = [{a:1}, {a:2}]
 | 
			
		||||
    var ob = Observer.create(arr)
 | 
			
		||||
 | 
			
		||||
    ob.on('mutate', spy)
 | 
			
		||||
    arr.push({a:3})
 | 
			
		||||
    expect(spy.mostRecentCall.args[0]).toEqual('')
 | 
			
		||||
    expect(spy.mostRecentCall.args[1]).toEqual(arr)
 | 
			
		||||
    var mutation = spy.mostRecentCall.args[2]
 | 
			
		||||
    expect(mutation).toBeDefined()
 | 
			
		||||
    expect(mutation.method).toEqual('push')
 | 
			
		||||
    expect(mutation.index).toEqual(2)
 | 
			
		||||
    expect(mutation.inserted.length).toEqual(1)
 | 
			
		||||
    expect(mutation.inserted[0]).toEqual(arr[2])
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  it('array set after mutate', function () {
 | 
			
		||||
    var arr = [{a:1}, {a:2}]
 | 
			
		||||
    var ob = Observer.create(arr)
 | 
			
		||||
    ob.on('set', spy)
 | 
			
		||||
    arr.push({a:3})
 | 
			
		||||
    arr[2].a = 4
 | 
			
		||||
    expect(spy).toHaveBeenCalledWith('2.a', 4, u)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  it('object.$add', function () {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue