Hello,
I’m trying to understand a performance difference of an order of
magnitude between the same sinatra code running on ruby 1.8.7 with
thin and on JRuby 1.6.0 deployed on JBoss 5.1.0.
I’ve added some simple execution time measurement using Time.now and I
get the following results:
Ruby 1.8.7: 0.107098s
JRuby 1.6.0: 1.433s
I’m sure I’m doing something wrong or I’ve tuned jRuby/JBoss wrongly,
but I don’t know exactly what.
You can find the code at http://pastebin.com/MZ9WaPQx with nice syntax
highlighting or below.
Thanks for any pointers in the right direction,
Johannes
P.S. The output of the code looks like the following:
{“aaData”:[[“22.03. 08h”,5.0],[“22.03. 10h”,5.8],[“22.03.
14h”,6.3],[“22.03. 20h”,6.1],[“23.03. 08h”,4.6],[“23.03.
10h”,6.4],[“23.03. 14h”,6.3],[“23.03. 20h”,5.5],[“24.03.
08h”,4.9],[“24.03.
10h”,7.0]],“iTotalRecords”:560,“iTotalDisplayRecords”:560,“sEcho”:“1”}
Code:
DataTables backend. See also DataTables - Usage
get
%r{^/patient/([\d]+)/table/(blood_pressure|blood_sugar|weight|alert|treatment)$}
do |patient_id,table|
start = Time.now
content_type :json
@user = get_user()
@patient = @user.get_patient(patient_id)
if @patient.nil?
raise Sinatra::NotFound
end
iDisplayStart = params[“iDisplayStart”].to_i
iDisplayStart = nil if iDisplayStart == 0
Fields and transformations for each table. See comment below.
fields = {
“blood_pressure” => [[[“time”], [“strftime”, “%d.%m. %Hh”]],
[[“systolic”]], [[“diastolic”]], [[“pulse”]]],
“blood_sugar” => [[[“time”], [“strftime”, “%d.%m. %Hh”]],
[[“glucose”], [“to_f”]]],
“weight” => [[[“time”], [“strftime”, “%d.%m. %Hh”]], [[“weight”],
[“to_f”]]],
“alert” => [[[“time”], [“strftime”, “%d.%m. %Hh”]],
[[“severity”]], [[“alert”]]],
“treatment” => [[[“time”], [“strftime”, “%d.%m. %Hh”]],
[[“slow_insulin_morning”]], [[“slow_insulin_night”]],
[[“fast_insulin_morning”]], [[“fast_insulin_lunch”]],
[[“fast_insulin_afternoon”]], [[“fast_insulin_evening”]],
[[“metformin_morning”]], [[“metformin_lunch”]],
[[“metformin_evening”]]]
}
Create a list of order terms as argument to sequel’s order function.
Results looks like [:time, :weight.desc]
iSortingCols = params[“iSortingCols”].to_i
order_by = if iSortingCols > 0
order_arr = []
table_fields = fields[table].length
iSortingCols.times do |n|
col_num = params[“iSortCol_#{n}”].to_i if
params[“iSortCol_#{n}”].match /^[0-9]/
col = fields[table][col_num][0][0].to_sym if col_num < table_fields
if not col.nil?
col = col.desc if params[“sSortDir_#{n}”] == “desc”
order_arr.push col
end
end
order_arr
else
[fields[table][0][0][0].to_sym.desc]
end
For aaData metaprogramming is used for general data driven code.
The list defined in fields is used to create a list of lists, where
each
list contains a data row.
[[“weight”], [“to_f”]] is thereby equivalent to row.weight.to_f
{
:iTotalRecords => @patient.agent.blood_pressures.count,
:iTotalDisplayRecords => @patient.agent.blood_pressures.count,
:sEcho => params[“sEcho”].to_i.to_s,
:aaData => @patient.agent.send(table + “s_dataset”).order(*order_by)
.limit(10,iDisplayStart).map do |row|
fields[table].map do |field|
field.reduce(row) do |obj,method|
obj.send(*method)
end
end
end
}.to_json
(Time.now - start).to_s
end