mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	Replace std::function with hyper_function for a 37% speedup in compile time.
Before:
    time c++ -O2 -DMAC -I/usr/local/include -std=c++11 -march=native
             -W -Wall -Wextra -Werror -pedantic -Wno-format-pedantic
             -Wno-missing-field-initializers -Wno-unused-parameter
             -DCAP_GLEW=0 -DCAP_PNG=0    -c hyper.cpp -o hyper.o
    real 2m22.508s
    user 2m20.625s
    sys  0m1.648s
After:
    time c++ -O2 -DMAC -I/usr/local/include -std=c++11 -march=native
             -W -Wall -Wextra -Werror -pedantic -Wno-format-pedantic
             -Wno-missing-field-initializers -Wno-unused-parameter
             -DCAP_GLEW=0 -DCAP_PNG=0    -c hyper.cpp -o hyper.o
    real 1m30.515s
    user 1m29.793s
    sys  0m0.689s
Comparing object file size:
    -rw-r--r--  1 ajo  staff  8215036 Jan  5 20:46 old-hyper.o
    -rw-r--r--  1 ajo  staff  7538072 Jan  5 20:47 new-hyper.o
Comparing number of symbols:
    nm old-hyper.o | wc -l  => 12590
    nm new-hyper.o | wc -l  =>  9742
No appreciable difference in link time; the linker takes less than
half a second in either case.
			
			
This commit is contained in:
		 Arthur O'Dwyer
					Arthur O'Dwyer
				
			
				
					committed by
					
						 Zeno Rogue
						Zeno Rogue
					
				
			
			
				
	
			
			
			 Zeno Rogue
						Zeno Rogue
					
				
			
						parent
						
							a478bb1485
						
					
				
				
					commit
					87240cf990
				
			
							
								
								
									
										4
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -7,6 +7,7 @@ | |||||||
| #define VERNUM_HEX 0xA505 | #define VERNUM_HEX 0xA505 | ||||||
|  |  | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
|  | #include "hyper_function.h" | ||||||
|  |  | ||||||
| namespace hr { | namespace hr { | ||||||
|  |  | ||||||
| @@ -15,6 +16,8 @@ void ignore(T&&) { | |||||||
|   // placate GCC's overzealous -Wunused-result |   // placate GCC's overzealous -Wunused-result | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | template<class Sig> using function = hyper_function<Sig>; | ||||||
|  |  | ||||||
| // functions and types used from the standard library | // functions and types used from the standard library | ||||||
| using std::vector; | using std::vector; | ||||||
| using std::map; | using std::map; | ||||||
| @@ -24,7 +27,6 @@ using std::sort; | |||||||
| using std::multimap; | using std::multimap; | ||||||
| using std::set; | using std::set; | ||||||
| using std::string; | using std::string; | ||||||
| using std::function; |  | ||||||
| using std::pair; | using std::pair; | ||||||
| using std::tuple; | using std::tuple; | ||||||
| using std::shared_ptr; | using std::shared_ptr; | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								hyper_function.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								hyper_function.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <type_traits> | ||||||
|  | #include <utility> | ||||||
|  |  | ||||||
|  | template<class Sig> | ||||||
|  | class hyper_function; | ||||||
|  |  | ||||||
|  | template<class R, class... Args> | ||||||
|  | struct hyper_function_state_base { | ||||||
|  |     virtual R call(Args...) const = 0; | ||||||
|  |     virtual hyper_function_state_base *clone() const = 0; | ||||||
|  |     virtual ~hyper_function_state_base() = default; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template<class T, class R, class... Args> | ||||||
|  | struct hyper_function_state : hyper_function_state_base<R, Args...> { | ||||||
|  |     using Self = hyper_function_state<T, R, Args...>; | ||||||
|  |     T t_; | ||||||
|  |     explicit hyper_function_state(T t) : t_(std::move(t)) {} | ||||||
|  |     R call(Args... args) const override { | ||||||
|  |         return const_cast<T&>(t_)(static_cast<Args&&>(args)...); | ||||||
|  |     } | ||||||
|  |     hyper_function_state_base<R, Args...> *clone() const override { | ||||||
|  |         return new Self(*this); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template<class R, class... Args> | ||||||
|  | class hyper_function<R(Args...)> | ||||||
|  | { | ||||||
|  |     hyper_function_state_base<R, Args...> *ptr_ = nullptr; | ||||||
|  | public: | ||||||
|  |     hyper_function() = default; | ||||||
|  |  | ||||||
|  |     template<class Callable, class = decltype(R(std::declval<typename std::decay<Callable>::type>()(std::declval<Args>()...)))> | ||||||
|  |     hyper_function(Callable&& t) : | ||||||
|  |         ptr_(new hyper_function_state<typename std::decay<Callable>::type, R, Args...>(static_cast<Callable&&>(t))) | ||||||
|  |     {} | ||||||
|  |  | ||||||
|  |     ~hyper_function() { | ||||||
|  |         delete ptr_; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     hyper_function(hyper_function& rhs) : ptr_(rhs.ptr_ ? rhs.ptr_->clone() : nullptr) {} | ||||||
|  |     hyper_function(const hyper_function& rhs) : ptr_(rhs.ptr_ ? rhs.ptr_->clone() : nullptr) {} | ||||||
|  |     hyper_function(hyper_function&& rhs) noexcept : ptr_(rhs.ptr_) { rhs.ptr_ = nullptr; } | ||||||
|  |     hyper_function(const hyper_function&& rhs) = delete; | ||||||
|  |  | ||||||
|  |     void operator=(hyper_function rhs) noexcept { | ||||||
|  |         std::swap(ptr_, rhs.ptr_); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     R operator()(Args... args) const { | ||||||
|  |         return ptr_->call(static_cast<Args&&>(args)...); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     explicit operator bool() const noexcept { | ||||||
|  |         return ptr_ != nullptr; | ||||||
|  |     } | ||||||
|  | }; | ||||||
		Reference in New Issue
	
	Block a user