Skip to content

Instantly share code, notes, and snippets.

@ctoestreich
Created November 3, 2011 21:36
Show Gist options
  • Save ctoestreich/1337848 to your computer and use it in GitHub Desktop.
Save ctoestreich/1337848 to your computer and use it in GitHub Desktop.
Custom Number Encoder Speed Test
def tests = 5000
def enm = {n, e-> encodeNumberMap(n, e).toString() }
def dnm = {n, e-> decodeNumberMap(n, e).toString() }
performTest("map", tests, getEncoderMap(), getDecoderMap(), enm, dnm)
def en = {n, e-> encodeNumber(n, e).toString() }
def dn = {n, e-> decodeNumber(n, e).toString() }
performTest("list", tests, getEncoder(), getEncoder(), en, dn)
def performTest(name, tests, encoder, decoder, encd, decd){
def decodeTime = [], encodeTime = []
def encodedNumber, decodedNumber, number
def random = new Random()
tests.times {
number = Math.abs(random.nextLong())
encodeTime << benchmark {
encodedNumber = encd.call(number, encoder)
}
decodeTime << benchmark {
decodedNumber = decd.call(encodedNumber, decoder)
}
//println "$number == $decodedNumber using coded $encodedNumber"
assert number.toString() == decodedNumber
}
println "$tests encode $name took ${(encodeTime.sum() / encodeTime.size())} ms each on avg and ${encodeTime.sum()} ms total"
println "$tests decode $name took ${(decodeTime.sum() / decodeTime.size())} ms each on avg and ${decodeTime.sum()} ms total"
println ""
}
def getEncoder(){
['1','2','3','4','5','6','7','8','9','0','-','=','!','@','#','$','%','^','&','*','(',')','_',
'+','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[',']',
'\\',';','\'',',','.','/','{','}','|',':','\"','<','>','?','`','~',' ','ä','Ä','Ü','Ö','ü']
}
def getDecoderMap(){
['1':0,'2':1,'3':2,'4':3,'5':4,'6':5,'7':6,'8':7,'9':8,'0':9,'-':10,'=':11,'!':12,'@':13,'#':14,'$':15,'%':16,'^':17,'&':18,'*':19,
'(':20,')':21,'_':22,'+':23,'a':24,'b':25,'c':26,'d':27,'e':28,'f':29,'g':30,'h':31,'i':32,'j':33,'k':34,'l':35,'m':36,'n':37,'o':38,'p':39,'q':40,
'r':41,'s':42,'t':43,'u':44,'v':45,'w':46,'x':47,'y':48,'z':49,'A':50,'B':51,'C':52,'D':53,'E':54,'F':55,'G':56,'H':57,'I':58,'J':59,'K':60,'L':61,
'M':62,'N':63,'O':64,'P':65,'Q':66,'R':67,'S':68,'T':69,'U':70,'V':71,'W':72,'X':73,'Y':74,'Z':75,'[':76,']':77,
'\\':78,';':79,'\'':80,',':81,'.':82,'/':83,'{':84,'}':85,'|':86,':':87,'\"':88,'<':89,'>':90,'?':91,'`':92,'~':93,' ':94,'ä':95,'Ä':96,'Ü':97,'Ö':98,'ü':99]
}
def getEncoderMap(){
//reverse map for encoder, probably would create the map manually for less execute time
Map encoderMap = [:]
getDecoderMap().collect{ encoderMap.put((it.value.toString().length() == 1 ? "0${it.value}".toString() : it.value.toString()), it.key) }
encoderMap
}
def decodeNumber(number, encoder){
String decoded = ""
Integer num = 0
String numberString = number.toString()
Integer token = numberString.length()-1
while(token >= 0){
encoder.eachWithIndex{o,i->
if(o == numberString[token])
num = i
return
}
decoded = decoded + (num.toString().length() == 1 ? "0$num" : num)
token-=1
}
(decoded.startsWith("0") ? decoded[1..decoded.length()-1] : decoded)
}
String encodeNumber(number, encoder){
String encoded = ""
String numberString = number.toString()
numberString = ((numberString.length() % 2) != 0 ? "0$numberString" : numberString)
Integer token = numberString.length()-1
while(token >= 0){
encoded += encoder[numberString[token-1..token].toInteger()]
token-=2
}
encoded
}
String decodeNumberMap(number, map){
String decoded = ""
String numberString = number.toString()
Integer num = 0
Integer token = numberString.length()-1
while(token >= 0){
num = map[numberString[token]]
decoded = decoded + (num.toString().length() == 1 ? "0$num" : num)
token-=1
}
(decoded.startsWith("0") ? decoded[1..decoded.length()-1] : decoded)
}
String encodeNumberMap(number, map){
String encoded = ""
String numberString = number.toString()
numberString = ((numberString.length() % 2) != 0 ? "0$numberString" : numberString)
Integer token = numberString.length()-1
while(token >= 0){
encoded += map[numberString[token-1..token].toString()].toString()
token-=2
}
encoded
}
Long benchmark(closure) {
def start = System.currentTimeMillis()
closure.call()
def now = System.currentTimeMillis()
now - start
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment