Skip to content

Instantly share code, notes, and snippets.

@KvanTTT
Last active July 4, 2022 08:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KvanTTT/e3b355f7e321fe7f52e11ea1aa0ecbce to your computer and use it in GitHub Desktop.
Save KvanTTT/e3b355f7e321fe7f52e11ea1aa0ecbce to your computer and use it in GitHub Desktop.
Constant folding benchmark
from dis import dis
import sys
import timeit
warm_up_count = 4
iteration_count = 256
class C:
C0=0
C1=1
C2=2
C3=3
C4=4
C5=5
C6=6
C7=7
C8=8
C9=9
C10=10
C11=11
C12=12
C13=13
C14=14
C15=15
C16=16
C17=17
C18=18
C19=19
C20=20
C21=21
C22=22
C23=23
C24=24
C25=25
C26=26
C27=27
C28=28
C29=29
C30=30
C31=31
def main(argv):
check_by_if_test = benchmark_average("check_by_if_test")
check_by_range_test = benchmark_average("check_by_range_test")
check_by_range_with_literals_test = benchmark_average("check_by_range_with_literals_test")
check_by_bitwise_test = benchmark_average("check_by_bitwise_test")
print(f"check_by_if_test: {check_by_if_test} ns")
print(f"check_by_range_test: {check_by_range_test} ns")
print(f"check_by_range_with_literals_test: {check_by_range_with_literals_test} ns")
print(f"check_by_bitwise_test: {check_by_bitwise_test} ns")
def benchmark_average(func_name):
func_call = f"{func_name}(7)"
setup_str = f"from __main__ import {func_name}"
print(f"function {func_name}:")
print("warm up...")
timeit.timeit(func_call, setup=setup_str, number=warm_up_count)
print("warm up completed.")
print("benchmark...")
avg_time = timeit.timeit(func_call, setup=setup_str, number=iteration_count) / iteration_count
print("benchmark completed.")
print("")
return int(round(avg_time * 1_000_000_000)) # return result in nanoseconds
def check_by_if_test(i):
return i == C.C0 or i == C.C1 or i == C.C2 or i == C.C3 or\
i == C.C4 or i == C.C5 or i == C.C6 or i == C.C7 or\
i == C.C8 or i == C.C9 or i == C.C10 or i == C.C11 or\
i == C.C12 or i == C.C13 or i == C.C14 or i == C.C15 or\
i == C.C16 or i == C.C17 or i == C.C18 or i == C.C19 or\
i == C.C20 or i == C.C21 or i == C.C22 or i == C.C23 or\
i == C.C24 or i == C.C25 or i == C.C26 or i == C.C27 or\
i == C.C28 or i == C.C29 or i == C.C30 or i == C.C31
def check_by_range_test(i):
return i in [C.C0, C.C1, C.C2, C.C3,
C.C4, C.C5, C.C6, C.C7,
C.C8, C.C9, C.C10, C.C11,
C.C12, C.C13, C.C14, C.C15,
C.C16, C.C17, C.C18, C.C19,
C.C20, C.C21, C.C22, C.C23,
C.C24, C.C25, C.C26, C.C27,
C.C28, C.C29, C.C30, C.C31]
def check_by_range_with_literals_test(i):
return i in [0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23,
24, 25, 26, 27,
28, 29, 30, 31]
def check_by_bitwise_test(i): # i within [0..63)
return (1 << i) & 0xFFFFFFFF != 0
if __name__ == '__main__':
main(sys.argv)
print("consts:")
dis(check_by_range_test)
print("literals:")
dis(check_by_range_with_literals_test)
const warmUpCount = 8
const iterationCount = 64
class C {}
C.C0=1
C.C1=1
C.C2=2
C.C3=3
C.C4=4
C.C5=5
C.C6=6
C.C7=7
C.C8=8
C.C9=9
C.C10=10
C.C11=11
C.C12=12
C.C13=13
C.C14=14
C.C15=15
no_folding_const_refs_test = benchmarkAverage(no_folding_const_refs_test);
no_folding_const_literals_test = benchmarkAverage(no_folding_const_literals_test);
folding_test = benchmarkAverage(folding_test);
console.log(`no_folding_const_refs_test: ${no_folding_const_refs_test} ns`)
console.log(`no_folding_const_literals_test: ${no_folding_const_literals_test} ns`)
console.log(`folding_test: ${folding_test} ns`)
function benchmarkAverage(func) {
console.log(`function ${func.name}:`)
console.log("warm up...")
for (let i = 0; i < warmUpCount; i++) {
func();
}
console.log("warm up completed.")
console.log("benchmark...")
let startTime = process.hrtime();
for (let i = 0; i < iterationCount; i++) {
func();
}
let elapsed = process.hrtime(startTime);
let elapsedNs = Math.round((elapsed[0] * 1e6 + elapsed[1] / 1e3) * 1000 / iterationCount);
console.log("benchmark completed.")
console.log("")
return elapsedNs;
}
function no_folding_const_refs_test() {
return (1 << C.C0) | (1 << C.C1) | (1 << C.C2) | (1 << C.C3) |
(1 << C.C4) | (1 << C.C5) | (1 << C.C6) | (1 << C.C7) |
(1 << C.C8) | (1 << C.C9) | (1 << C.C10) | (1 << C.C11) |
(1 << C.C12) | (1 << C.C13) | (1 << C.C14) | (1 << C.C15);
}
function no_folding_const_literals_test() {
return (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) |
(1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) |
(1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) |
(1 << 12) | (1 << 13) | (1 << 14) | (1 << 15);
}
function folding_test() {
return 0xFFFF
}
import sys
import timeit
warm_up_count = 1
iteration_count = 64
class C:
C0=1
C1=1
C2=2
C3=3
C4=4
C5=5
C6=6
C7=7
C8=8
C9=9
C10=10
C11=11
C12=12
C13=13
C14=14
C15=15
def main(argv):
no_folding_const_refs_test = benchmark_average("no_folding_const_refs_test")
no_folding_const_literals_test = benchmark_average("no_folding_const_literals_test")
folding = benchmark_average("folding_test")
print(f"no_folding_const_refs_test: {no_folding_const_refs_test} ns")
print(f"no_folding_const_literals_test: {no_folding_const_literals_test} ns")
print(f"folding: {folding} ns")
def benchmark_average(func_name):
func_call = f"{func_name}()"
setup_str = f"from __main__ import {func_name}"
print(f"function {func_name}:")
print("warm up...")
timeit.timeit(func_call, setup=setup_str, number=warm_up_count)
print("warm up completed.")
print("benchmark...")
avg_time = timeit.timeit(func_call, setup=setup_str, number=iteration_count) / iteration_count
print("benchmark completed.")
print("")
return int(round(avg_time * 1_000_000_000)) # return result in nanoseconds
def no_folding_const_refs_test():
return (1 << C.C0) | (1 << C.C1) | (1 << C.C2) | (1 << C.C3) | \
(1 << C.C4) | (1 << C.C5) | (1 << C.C6) | (1 << C.C7) | \
(1 << C.C8) | (1 << C.C9) | (1 << C.C10) | (1 << C.C11) | \
(1 << C.C12) | (1 << C.C13) | (1 << C.C14) | (1 << C.C15)
def no_folding_const_literals_test():
return (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | \
(1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | \
(1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | \
(1 << 12) | (1 << 13) | (1 << 14) | (1 << 15)
def folding_test():
return 0xFFFF
if __name__ == '__main__':
main(sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment