Clojure从数据库获取数据,转换并打印到控制台
问题描述:
我有以下任务。
我需要创建一个控制台应用程序,它需要一个参数,它是要生成的数据的数量。数据是人员地址和姓名。我创建了一个表adress
和state, city, zip-code
字段。我还创建了一个包含first
和last name
列的表格。我使用HugSQL来处理PostgreSQL。所以我想动态地混合地址,名字和姓氏,并将这样的结果打印到控制台中,生成值的数量取决于传递给应用程序的参数。这是我的代码:Clojure从数据库获取数据,转换并打印到控制台
(ns project.core
(:require
[project.db.get :as get]))
(defn parse-int [s]
(Integer. (re-find #"\d+" s)))
(def usa-data (get/usa))
(defn usa-adress-getter []
(let [data (into {} (shuffle usa-data))
city (get data :city)
state (get data :state)
zip (get data :zip_code)]
(str state " " city " " zip)))
(defn repeater [times]
(dotimes [i times]
(println (usa-adress-getter))))
(defn -main [value]
(repeater (parse-int value)))
这里我只是检查usa-adress-getter
函数的结果。但功能评估的时间太长,我有限制,在1分钟内是100万的值。如何提高评估速度? 功能(get/usa)
检索adress
表中的所有数据。
答
你很难从这段代码中的性能瓶颈是这么说,但这里有一些提示:
- 的热点使用类型提示。有时Clojure编译器无法弄清楚类型,然后输入提示可以加快速度。在这种情况下,您可以将其设置为
usa-address-getter
fn:(defn ^String usa-adress-getter [] ...)
- 您可以考虑修改您的查询,以便它从数据库返回连接的字符串(使用SQL函数,如
concat
)。这样,你不需要从哈希中获取值并自己构建字符串。 - 打印的东西可能会很慢,所以你可以消除,就像@leetwinsky说。
- 你必须详细测量你的代码的性能,否则你将无法判断修改是否提高了你的速度。例如,您可以放置一个计时器,为处理的每1000条记录输出msecs数。当然,一次只能做一个改变。
希望这会有所帮助。
你的'usa-address-getter'看起来很奇怪。它甚至能正常工作吗?它真的不应该,因为你用'project.db/get'来映射'clojure.core/get'。请检查代码 – leetwinski
也是'(进入{}(shuffle usa-data))'看起来很可疑,因为美国数据应该返回一系列记录,所以将它添加到地图看起来就像是一个非现实。也许它应该是'(到{}(首先(洗牌美国数据)))'?无论如何,这看起来是低性能的关键:你在每次迭代中急切地洗牌数百万个项目,而且它真的很慢(我的机器上大约有250毫秒)。我建议你使用'rand-nth':'(into {}(rand-nth usa-data))' – leetwinski
,如果它不是强制性的逐一打印记录的话,可能会更好地构造整个集合,然后只是打印一次..像'(clojure.pprint/pprint(重复(parse-int值)usa-address-getter))'并抛出'repeater'函数 – leetwinski