Skip to content

Commit

Permalink
Replace path.getabsolute and path.getrelative with C versions
Browse files Browse the repository at this point in the history
These functions were showing up as hotspots in benchmarks. The
new C versions perform as much as 100x faster depending on the
complexity of the paths being handled.
  • Loading branch information
Brett Vickers committed Feb 6, 2017
1 parent 8c099a5 commit 370a54d
Show file tree
Hide file tree
Showing 12 changed files with 371 additions and 112 deletions.
24 changes: 24 additions & 0 deletions build/gmake.darwin/genie.make
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ ifeq ($(config),release)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -189,6 +192,9 @@ ifeq ($(config),debug)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -271,6 +277,9 @@ ifeq ($(config),releaseuniv32)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -353,6 +362,9 @@ ifeq ($(config),debuguniv32)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -603,6 +615,18 @@ $(OBJDIR)/src/host/os_uuid.o: ../../src/host/os_uuid.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_getabsolute.o: ../../src/host/path_getabsolute.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_getrelative.o: ../../src/host/path_getrelative.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_helpers.o: ../../src/host/path_helpers.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_isabsolute.o: ../../src/host/path_isabsolute.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"
Expand Down
18 changes: 18 additions & 0 deletions build/gmake.freebsd/genie.make
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ ifeq ($(config),release)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -183,6 +186,9 @@ ifeq ($(config),debug)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -429,6 +435,18 @@ $(OBJDIR)/src/host/os_uuid.o: ../../src/host/os_uuid.c $(GCH) genie.make
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_getabsolute.o: ../../src/host/path_getabsolute.c $(GCH) genie.make
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_getrelative.o: ../../src/host/path_getrelative.c $(GCH) genie.make
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_helpers.o: ../../src/host/path_helpers.c $(GCH) genie.make
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_isabsolute.o: ../../src/host/path_isabsolute.c $(GCH) genie.make
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"
Expand Down
18 changes: 18 additions & 0 deletions build/gmake.linux/genie.make
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ ifeq ($(config),release)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -189,6 +192,9 @@ ifeq ($(config),debug)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -439,6 +445,18 @@ $(OBJDIR)/src/host/os_uuid.o: ../../src/host/os_uuid.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_getabsolute.o: ../../src/host/path_getabsolute.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_getrelative.o: ../../src/host/path_getrelative.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_helpers.o: ../../src/host/path_helpers.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_isabsolute.o: ../../src/host/path_isabsolute.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"
Expand Down
18 changes: 18 additions & 0 deletions build/gmake.windows/genie.make
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ ifeq ($(config),release)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -189,6 +192,9 @@ ifeq ($(config),debug)
$(OBJDIR)/src/host/os_stat.o \
$(OBJDIR)/src/host/os_ticks.o \
$(OBJDIR)/src/host/os_uuid.o \
$(OBJDIR)/src/host/path_getabsolute.o \
$(OBJDIR)/src/host/path_getrelative.o \
$(OBJDIR)/src/host/path_helpers.o \
$(OBJDIR)/src/host/path_isabsolute.o \
$(OBJDIR)/src/host/premake.o \
$(OBJDIR)/src/host/premake_main.o \
Expand Down Expand Up @@ -439,6 +445,18 @@ $(OBJDIR)/src/host/os_uuid.o: ../../src/host/os_uuid.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_getabsolute.o: ../../src/host/path_getabsolute.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_getrelative.o: ../../src/host/path_getrelative.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_helpers.o: ../../src/host/path_helpers.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"

$(OBJDIR)/src/host/path_isabsolute.o: ../../src/host/path_isabsolute.c $(GCH) $(MAKEFILE)
@echo $(notdir $<)
$(SILENT) $(CC) $(ALL_CFLAGS) $(FORCE_INCLUDE) -o "$@" -c "$<"
Expand Down
99 changes: 0 additions & 99 deletions src/base/path.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,6 @@
--


--
-- Get the absolute file path from a relative path. The requested
-- file path doesn't actually need to exist.
--

function path.getabsolute(p)
-- normalize the target path
p = path.translate(p, "/")
if (p == "") then p = "." end

-- if the directory is already absolute I don't need to do anything
local result = iif (path.isabsolute(p), nil, os.getcwd())

-- split up the supplied relative path and tackle it bit by bit
for n, part in ipairs(p:explode("/", true)) do
if (part == "" and n == 1) then
result = "/"
elseif (part == "..") then
result = path.getdirectory(result)
elseif (part ~= ".") then
-- Environment variables embedded in the path need to be treated
-- as relative paths; path.join() makes them absolute
if (part:startswith("$") and n > 1) then
result = result .. "/" .. part
else
result = path.join(result, part)
end
end
end

-- if I end up with a trailing slash remove it
result = iif(result:endswith("/"), result:sub(1, -2), result)

return result
end


--
-- Retrieve the filename portion of a path, without any extension.
--
Expand Down Expand Up @@ -128,68 +91,6 @@
end


--
-- Returns the relative path from src to dest.
--

function path.getrelative(src, dst)
-- normalize the two paths
src = path.getabsolute(src)
dst = path.getabsolute(dst)

-- same directory?
if (src == dst) then
return "."
end

-- dollar macro? Can't tell what the real path is; use absolute
-- This enables paths like $(SDK_ROOT)/include to work correctly.
if dst:startswith("$") then
return dst
end

src = src .. "/"
dst = dst .. "/"

-- find the common leading directories
local idx = 0
while (true) do
local tst = src:find("/", idx + 1, true)
if tst then
if src:sub(1,tst) == dst:sub(1,tst) then
idx = tst
else
break
end
else
break
end
end

-- if they have nothing in common return absolute path
local first = src:find("/", 0, true)
if idx <= first then
return dst:sub(1, -2)
end

-- trim off the common directories from the front
src = src:sub(idx + 1)
dst = dst:sub(idx + 1)

-- back up from dst to get to this common parent
local result = ""
idx = src:find("/")
while (idx) do
result = result .. "../"
idx = src:find("/", idx + 1)
end

-- tack on the path down to the dst from here
result = result .. dst

-- remove the trailing slash
return result:sub(1, -2)
end

--
-- Returns the common base directory of two paths.
Expand Down
15 changes: 15 additions & 0 deletions src/host/path_getabsolute.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* \file path_getabsolute.c
* \brief Calculate the absolute path from a relative path
*/

#include "premake.h"

int path_getabsolute(lua_State *L)
{
const char *path = luaL_checkstring(L, -1);
char buffer[PATH_BUFSIZE];
get_absolute_path(path, buffer, PATH_BUFSIZE);
lua_pushstring(L, buffer);
return 1;
}
16 changes: 16 additions & 0 deletions src/host/path_getrelative.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* \file path_getrelative.c
* \brief Calculate the relative path from src to dest
*/

#include "premake.h"

int path_getrelative(lua_State *L)
{
const char *src = luaL_checkstring(L, -2);
const char *dst = luaL_checkstring(L, -1);
char buffer[PATH_BUFSIZE];
get_relative_path(src, dst, buffer, PATH_BUFSIZE);
lua_pushstring(L, buffer);
return 1;
}
Loading

0 comments on commit 370a54d

Please sign in to comment.