2017-10-10 108 views
0

我有以下任务。
我需要创建一个控制台应用程序,它需要一个参数,它是要生成的数据的数量。数据是人员地址和姓名。我创建了一个表adressstate, city, zip-code字段。我还创建了一个包含firstlast 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表中的所有数据。

+0

你的'usa-address-getter'看起来很奇怪。它甚至能正常工作吗?它真的不应该,因为你用'project.db/get'来映射'clojure.core/get'。请检查代码 – leetwinski

+0

也是'(进入{}(shuffle usa-data))'看起来很可疑,因为美国数据应该返回一系列记录,所以将它添加到地图看起来就像是一个非现实。也许它应该是'(到{}(首先(洗牌美国数据)))'?无论如何,这看起来是低性能的关键:你在每次迭代中急切地洗牌数百万个项目,而且它真的很慢(我的机器上大约有250毫秒)。我建议你使用'rand-nth':'(into {}(rand-nth usa-data))' – leetwinski

+0

,如果它不是强制性的逐一打印记录的话,可能会更好地构造整个集合,然后只是打印一次..像'(clojure.pprint/pprint(重复(parse-int值)usa-address-getter))'并抛出'repeater'函数 – leetwinski

回答

0

你很难从这段代码中的性能瓶颈是这么说,但这里有一些提示:

  • 的热点使用类型提示。有时Clojure编译器无法弄清楚类型,然后输入提示可以加快速度。在这种情况下,您可以将其设置为usa-address-getter fn:(defn ^String usa-adress-getter [] ...)
  • 您可以考虑修改您的查询,以便它从数据库返回连接的字符串(使用SQL函数,如concat)。这样,你不需要从哈希中获取值并自己构建字符串。
  • 打印的东西可能会很慢,所以你可以消除,就像@leetwinsky说。
  • 你必须详细测量你的代码的性能,否则你将无法判断修改是否提高了你的速度。例如,您可以放置​​一个计时器,为处理的每1000条记录输出msecs数。当然,一次只能做一个改变。

希望这会有所帮助。