diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index 7e08f6157699d3ec8ff6fcfbf0396d80676090d1..5f97e3730fa129d33988832f1a1457432dd34dcc 100755
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -8795,9 +8795,6 @@ proto="""
 """)
 
 
-# TODO: __Pyx_CyFunction_NewEx implicitly uses the global module
-# to get func_globals. This will need to be passed in if we share
-# this type accross modules. 
 binding_cfunc_utility_code = UtilityCode(
 proto="""
 #define __Pyx_CyFunction_USED 1
@@ -8809,7 +8806,6 @@ typedef struct {
     PyObject *func_weakreflist;
     PyObject *func_name;
     PyObject *func_doc;
-    PyObject *func_globals;
 } __pyx_CyFunctionObject;
 
 static PyTypeObject *__pyx_CyFunctionType = 0;
@@ -8820,7 +8816,7 @@ static int __Pyx_CyFunction_init(void);
 """ % Naming.__dict__,
 impl="""
 static PyObject *
-__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure)
+__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure)
 {
     if (op->func_doc == NULL && op->func.m_ml->ml_doc) {
 #if PY_MAJOR_VERSION >= 3
@@ -8886,7 +8882,7 @@ __Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value)
 }
 
 static PyObject *
-__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, void *closure)
+__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure)
 {
     PyObject *self;
 
@@ -8930,21 +8926,24 @@ __Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value)
     Py_XDECREF(tmp);
     return 0;
 }
-
+""" + (
+# TODO: we implicitly use the global module to get func_globals.  This
+# will need to be passed into __Pyx_CyFunction_NewEx() if we share
+# this type accross modules.  We currently avoid doing this to reduce
+# the overhead of creating a function object, and to avoid keeping a
+# reference to the module dict as long as we don't need to.
+"""
 static PyObject *
-__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op)
+__Pyx_CyFunction_get_globals(CYTHON_UNUSED __pyx_CyFunctionObject *op)
 {
-    if (op->func_globals == NULL) {
-        op->func_globals = PyDict_New();
-        if (op->func_globals == NULL)
-            return NULL;
-    }
-    Py_INCREF(op->func_globals);
-    return op->func_globals;
+    PyObject* dict = PyModule_GetDict(%(module_cname)s);
+    Py_XINCREF(dict);
+    return dict;
 }
-
+""" % Naming.__dict__ ) +
+"""
 static PyObject *
-__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op)
+__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op)
 {
     Py_INCREF(Py_None);
     return Py_None;
@@ -9003,7 +9002,6 @@ static PyObject *__Pyx_CyFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObjec
     op->func_dict = NULL;
     op->func_name = NULL;
     op->func_doc = NULL;
-    op->func_globals = PyObject_GetAttrString(%(module_cname)s, (char *)"__dict__");
     PyObject_GC_Track(op);
     return (PyObject *)op;
 }
@@ -9018,7 +9016,6 @@ static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
     Py_XDECREF(m->func_dict);
     Py_XDECREF(m->func_name);
     Py_XDECREF(m->func_doc);
-    Py_XDECREF(m->func_globals);
     PyObject_GC_Del(m);
 }
 
@@ -9029,7 +9026,6 @@ static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit,
     Py_VISIT(m->func_dict);
     Py_VISIT(m->func_name);
     Py_VISIT(m->func_doc);
-    Py_VISIT(m->func_globals);
     return 0;
 }
 
@@ -9046,10 +9042,10 @@ __Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
     PyObject *func_name = __Pyx_CyFunction_get_name(op);
 
 #if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromFormat("<cyfunction %%U at %%p>",
+    return PyUnicode_FromFormat("<cyfunction %U at %p>",
                                func_name, op);
 #else
-    return PyString_FromFormat("<cyfunction %%s at %%p>",
+    return PyString_FromFormat("<cyfunction %s at %p>",
                                PyString_AsString(func_name), op);
 #endif
 }
@@ -9118,7 +9114,7 @@ static int __Pyx_CyFunction_init(void)
     __pyx_CyFunctionType = &__pyx_CyFunctionType_type;
     return 0;
 }
-""" % Naming.__dict__)
+""")
 
 generator_utility_code = UtilityCode(
 proto="""
diff --git a/tests/run/cyfunction.pyx b/tests/run/cyfunction.pyx
index 1399bc4d02e5b41344b29e22b570618a16055cfa..c791641e75cffca2e288f58d950dc801bac10467 100644
--- a/tests/run/cyfunction.pyx
+++ b/tests/run/cyfunction.pyx
@@ -39,6 +39,27 @@ def test_doc():
     'docstring'
     """
 
+def test_closure():
+    """
+    >>> test_closure.func_closure is None
+    True
+    """
+
+def test_globals():
+    """
+    >>> test_globals.func_globals is not None
+    True
+    >>> 'test_globals' in test_globals.func_globals or test_globals.func_globals
+    True
+    >>> 'test_name' in test_globals.func_globals or test_globals.func_globals
+    True
+    >>> 'not there' not in test_globals.func_globals or test_globals.func_globals
+    True
+    >>> try: test_globals.func_globals = {}
+    ... except (AttributeError, TypeError): pass
+    ... else: assert 0, 'FAILED'
+    """
+
 def test_reduce():
     """
     >>> import pickle