Skip to content

Instantly share code, notes, and snippets.

@elrayle
Last active August 29, 2015 14:09
Show Gist options
  • Save elrayle/f5f559f8c10243600dc6 to your computer and use it in GitHub Desktop.
Save elrayle/f5f559f8c10243600dc6 to your computer and use it in GitHub Desktop.
Ruby array limit testing using List Item Info datastructure as each item in the array
class Array
def move(from,to)
insert(to, delete_at(from))
end
end
def gen_list(max_items)
items = []
header_info = {}
header_info[:uri] = "http://localhost/list/acc1e0e4-5676-4594-833b-cca6ec6bf361"
header_info[:first] = "http://localhost/proxy/p1"
header_info[:last] = "http://localhost/proxy/p#{(max_items)}"
header_info[:current] = 6
header_info[:last_loaded] = max_items
header_info[:count_loaded] = max_items
header_info[:resume_next_token] = nil
header_info[:resume_prev_token] = nil
header_info[:loaded_items] = items
0.upto(max_items) do |i|
item_info = {}
item_info[:uri] = "http://localhost/proxy/p#{i}"
item_info[:prev] = i == 0 ? nil : "http://localhost/proxy/p#{(i-1)}"
item_info[:next] = i > max_items ? nil : "http://localhost/proxy/p#{(i+1)}"
item_info[:proxyFor] = "http://localhost/bibref/b#{i}"
item_info[:proxyIn] = "http://localhost/list/acc1e0e4-5676-4594-833b-cca6ec6bf361"
item_info[:proxyIn_loaded] = header_info
items[i] = item_info
# print "." if max_items <= 80 || i.modulo(max_items/80) == 0
end
header_info
end
def move_item(list,to,from)
items = list[:loaded_items]
return nil unless from >= 0 && from < items.size ### TODO Give warning that list wasn't changed because from is too small or too big
return nil unless to >= 0 && to < items.size ### TODO Give warning that list wasn't changed because to is too small or too big
items.move(to,from)
# update from location links
items[from+1][:prev] = items[from][:uri] unless from == (list[:loaded_items].size-1)
items[from][:prev] = from == 0 ? nil : items[from-1][:uri]
items[from][:next] = from == (list[:loaded_items].size-1) ? nil : items[from+1][:uri]
items[from-1][:next] = items[from][:uri] unless from == 0
# update to location links
items[to+1][:prev] = items[to][:uri] unless to == (list[:loaded_items].size-1)
items[to][:prev] = to == 0 ? nil : items[to-1][:uri]
items[to][:next] = to == (list[:loaded_items].size-1) ? nil : items[to+1][:uri]
items[to-1][:next] = items[to][:uri] unless to == 0
nil
end
def insert_item(list,item,before)
items = list[:loaded_items]
return nil unless before >= 0 && before <= items.size ### TODO Give warning that list wasn't changed because from is too small or too big
items.insert(before,item)
# update from location links
items[before+1][:prev] = items[before][:uri] unless before == (items.size-1)
items[before][:prev] = before == 0 ? nil : items[before-1][:uri]
items[before][:next] = before == (items.size-1) ? nil : items[before+1][:uri]
items[before-1][:next] = items[before][:uri] unless before == 0
nil
end
def append_item(list,item)
items = list[:loaded_items]
items.insert(items.size,item)
nil
end
def find_item_by_uri(list,uri)
items = list[:loaded_items]
0.upto(items.size-1) { |i| return i if items[i][:uri] == uri }
nil
end
def destroy_list(list)
# garbage collection does not seem to happen even with GC.start
list[:loaded_items].clear
list = nil
GC.start
end
def find_random_items(list,num)
items = list[:loaded_items]
max = items.size
t = 0
1.upto(num) do |i|
uri = "http://localhost/proxy/p#{rand(max)}"
t_start = 0
t_end = 0
t_start = Time.now.to_i
idx = find_item_by_uri(list,uri)
t_end = Time.now.to_i
# ret_time[:array_create] = t_end - t_start
puts("random_find[#{i}] for #{max}: #{t_end-t_start} sec -- URI: #{uri} -- POS: #{idx}")
t += t_end - t_start
end
avg = t/num
puts("random_find avg for #{max}: #{avg}")
avg
end
def test_at_scale(max_items, array_test=false, list_test=false)
ret_time = {}
if array_test
# simple array create test
t_start = 0
t_end = 0
t_start = Time.now.to_i
a = []
a.fill(0,max_items) {|i| ++i }
# a.fill(0,max_items) {|i| ++i; print "." if max_items <= 80 || i.modulo(max_items/80) == 0 }
t_end = Time.now.to_i
ret_time[:array_create] = t_end - t_start
puts("\narray_create for #{max_items}: #{t_end-t_start} sec")
# simple array move test
t_start = 0
t_end = 0
t_start = Time.now.to_i
a.move(max_items-2,1); print "."
t_end = Time.now.to_i
ret_time[:array_move] = t_end - t_start
puts("\narray_move for #{max_items}: #{t_end-t_start} sec")
# garbage collection does not seem to happen even with GC.start
a.clear
a = nil
GC.start
end
if list_test
# list create test
t_start = 0
t_end = 0
t_start = Time.now.to_i
l = gen_list(max_items)
t_end = Time.now.to_i
ret_time[:list_create] = t_end - t_start
puts("\nlist_create for #{max_items}: #{t_end-t_start} sec")
# list move item test - from near end of list to near beginning of list
t_start = 0
t_end = 0
t_start = Time.now.to_i
move_item(l,max_items-2,1); print "."
t_end = Time.now.to_i
ret_time[:list_move] = t_end - t_start
puts("\nlist_move for #{max_items}: #{t_end-t_start} sec")
# list insert item test - near beginning of list
t_start = 0
t_end = 0
t_start = Time.now.to_i
insert_item(l,l[:loaded_items][0],1); print "."
t_end = Time.now.to_i
ret_time[:list_insert] = t_end - t_start
puts("\nlist_insert for #{max_items}: #{t_end-t_start} sec")
# list append item test
t_start = 0
t_end = 0
t_start = Time.now.to_i
append_item(l,l[:loaded_items][0]); print "."
t_end = Time.now.to_i
ret_time[:list_append] = t_end - t_start
puts("\nlist_append for #{max_items}: #{t_end-t_start} sec")
# find last item by uri
t_start = 0
t_end = 0
t_start = Time.now.to_i
idx = find_item_by_uri(l,"http://localhost/proxy/p#{max_items-1}"); print "."
t_end = Time.now.to_i
ret_time[:list_find] = t_end - t_start
puts("\nlist_find for #{max_items}: #{t_end-t_start} sec found - position=#{idx}")
# find item by non-existent uri
t_start = 0
t_end = 0
t_start = Time.now.to_i
idx = find_item_by_uri(l,"MISSING"); print "."
t_end = Time.now.to_i
ret_time[:list_find] = t_end - t_start
puts("\nlist_find for #{max_items}: #{t_end-t_start} sec NOT found - position=#{idx}")
# find items by random uri
avg = find_random_items(l,[max_items,200].min)
ret_time[:rand_find] = avg
puts("\nrand_find for #{max_items}: #{avg} sec on average")
# garbage collection does not seem to happen even with GC.start
destroy_list(l)
end
ret_time
end
# NOTE: Each test needs to be run with a fresh irb session. Garbage Collection does
# not fully release memory and will give inaccurate results if all tests are run in
# the same irb session.
ta_10 = test_at_scale(10,true,false)
ta_100 = test_at_scale(100,true,false)
ta_1_000 = test_at_scale(1000,true,false)
ta_10_000 = test_at_scale(10000,true,false)
ta_100_000 = test_at_scale(100000,true,false)
ta_500_000 = test_at_scale(500000,true,false)
ta_1_000_000 = test_at_scale(1000000,true,false)
ta_2_000_000 = test_at_scale(2000000,true,false)
ta_4_000_000 = test_at_scale(4000000,true,false)
ta_8_000_000 = test_at_scale(8000000,true,false)
ta_10_000_000 = test_at_scale(10000000,true,false)
ta_20_000_000 = test_at_scale(20000000,true,false)
ta_40_000_000 = test_at_scale(40000000,true,false)
ta_80_000_000 = test_at_scale(80000000,true,false)
ta_100_000_000 = test_at_scale(100000000,true,false)
tl_10 = test_at_scale(10,false,true)
tl_100 = test_at_scale(100,false,true)
tl_1_000 = test_at_scale(1000,false,true)
tl_10_000 = test_at_scale(10000,false,true)
tl_100_000 = test_at_scale(100000,false,true)
tl_500_000 = test_at_scale(500000,false,true)
tl_1_000_000 = test_at_scale(1000000,false,true)
tl_2_000_000 = test_at_scale(2000000,false,true)
tl_4_000_000 = test_at_scale(4000000,false,true)
tl_8_000_000 = test_at_scale(8000000,false,true)
tl_10_000_000 = test_at_scale(10000000,false,true)
tl_20_000_000 = test_at_scale(20000000,false,true)
tl_40_000_000 = test_at_scale(40000000,false,true)
tl_80_000_000 = test_at_scale(80000000,false,true)
tl_100_000_000 = test_at_scale(100000000,false,true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment